feat(spec)!: 收紧 responsive/SDUI 样式形状的未知键,并把另外五个文件按实测改判(#4001 批 13) - #5003
Merged
Conversation
#4001 批 13) Close all four sites in `ui/responsive.zod.ts` with `strictObject`. The nested gap is what this fixes: `PageComponentSchema` has been `.strict()` since ADR-0089 D3a and strictness does not recurse, so a component whose every styling and layout instruction was written in the wrong breakpoint vocabulary parsed clean and returned `{ responsiveStyles: {}, responsive: {} }`. The file carries TWO breakpoint vocabularies sixteen lines apart on the same component (ADR-0065 buckets vs the Tailwind ramp), so the aliases run both ways and are anchored to the named sibling rather than to edit distance. The other five files in this batch are NOT closed, on a measurement: their 22 sites have no authoring door (no carrier key; unreachable by BFS from all 24 metadata-type roots plus defineStack, with three positive controls passing in the same run; no .parse() anywhere in three repos). ADR-0049 triage is #4988. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
…tness (#4001 批 13) The door is getMetadataTypeSchema('page') — MetadataManager.validate, GET /api/v1/meta, the Studio page form. It is NOT objectstack build/validate: a key PageComponentSchema has rejected since ADR-0089 D3a passes both and lands in the built artifact. Pre-existing, filed as #5000; recorded here so the campaign's usual "three example apps validate" line is not read as evidence for this surface. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
|
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 20:02
xuyushun441-sys
enabled auto-merge
August 3, 2026 20:02
xuyushun441-sys
pushed a commit
that referenced
this pull request
Aug 4, 2026
Brings in #5003 (批 13), #5006, #4983, #4991, #4855, #4729, #4250. Ledger `ui/` section conflicted, as planned — 批 13 and 批 14 both edit it. Every row from both sides kept; nothing resolved in favour of a side: - classification table: ONE merged `no door` row (批 13 authored the class; 批 14 adds the positive-control requirement and the first file that SPLITS across it, ui/sharing.zod.ts). - triage table: structure from 批 13 (it split `responsive` out and grouped the five no-door files); 批 14's four measured verdicts overlaid. - remaining-strip map: `responsive` row deleted by 批 13, `action`/`report`/ `dataset`/`dashboard` rows deleted by 批 14 — all five by the reverse pin. Header and subtotal RECOMPUTED FROM THE SURVIVING ROWS, not decremented: 29+20+14+9+7+7+6+4+4+4+3+1+1+1 = 110. 批 13 wrote 119 (against a tree where 批 14's four rows still existed), 批 14 wrote 114 (against one where `responsive` still did); both were right against their own branch and both are wrong against the merge. The fifth and sixth instances of the failure the automation/ section documents, and the first where the two wrong numbers were both this line. Subtotal 88 of 110 authorable, 22 in the fourth class. check:strictness-ledger arbitrates and is green. os-regen four-step: merged (never rebased), refreshed install + spec build, reset all seven generator-owned paths to origin/main, regenerated wholesale. Delta vs origin/main is exactly one file — content/docs/references/ui/sharing.mdx — so the regeneration reproduced main's artifacts byte-identically and no sibling entry was dropped (#5006's RateLimitConfig/RateLimitConfigSchema and 批 13's responsive entries confirmed present). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
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.
Part of #4001 ——
ui/方向的第一波(批 13),六个交互/呈现配置文件,账本重测记的 ~26 个 strip 站点。结论先说:6 个文件里只有 1 个该收紧
批 13 的六个文件账本上全是
authorable (p)—— (p) 是待验证,不是结论。逐个解(p)之后:(p)解出来是responsive.zod.tsstrictObjecttouch.zod.tsanimation.zod.tsdnd.zod.tskeyboard.zod.tsoffline.zod.ts批 10(state-machine)和批 11(webhook)解
(p)时都找到了账本没记的门,这留下一个「验证 = 找门」的隐含预期。批 13 用同一套程序、同一次运行里带阳性对照,连着五个文件没找到任何门 —— 而验证步骤的正确输出就是它测到的东西,包括「这从来就不是棘轮的活」。一、
responsive.zod.ts—— 收紧的那一个(p)解在图上而不是在文件表面:page.components[].responsive/.responsiveStyles把两个形状放进了page这个 metadata-type root。(dashboard.widgets[].responsive是第二个承载键,同日被 #4876 退役,本 PR 已合并其变更并联测。)收紧真正补的是一个嵌套洞。
PageComponentSchema自 ADR-0089 D3a 起就是.strict(),而严格性不递归,所以这个组件在main上解析是干净通过的:作者写的每一条样式和布局指令,全没了,报告有效。一个 strict 的壳套着 strip 的子块,不是一个关上的面,是关上的面的剪影。
策展锚在同文件的兄弟契约上,不是编辑距离(批 12 的方法)
这个文件在同一个页面组件上、相隔十六行载着两套断点词汇:
responsiveStyles是 ADR-0065 的 desktop-first 桶(large/medium/small/xsmall),responsive是文件顶部BreakpointName的 Tailwind 阶梯(xs…2xl)。两套都对,互相不是错别字,编辑距离也过不去(lg→large)。所以别名双向都配。两条是测出来的,不是推出来的:
{ columns: { large: 4, lg: 3 } }过去会保留一半的 map —— 节点确实布局了,在错误的宽度上、在作者从没点名的断点上。这比全丢更坏,全丢至少是看得见的。hideOn→hiddenOn必须手写别名,因为兜底证明够不着:findClosestMatches把输入小写化、候选不小写化,于是声明键里每个大写字母白扣一次编辑距离 ——hideOn对预算 2 算出 3,而全小写的hiddenon算出 1 反而给得出建议。这条不对称对 camelCase 键是普遍的(按 AGENTS.md 命名约定,即 spec 的绝大多数键),单独归档为 未知键的「你是不是想写」兜底对 camelCase 键系统性偏弱:输入被小写化、候选没有 —— 每个大写字母白扣一次编辑距离 #4990。两条是处方而非改名:
responsive层上的裸断点名(退役的view.responsive那套 breakpoint-keyed 形状,#3896;转换注册表里还留着responsive: { sm: {} }这个 fixture)三个键都可能是目标,所以逐键给独立文案 ——guidance每个键原样发一条 bullet,共享字符串会把同一段打印 N 次(批 10join/joinGateway的教训)。以及两套词汇互相写错时,指向同组件上的兄弟键。StyleMapSchema故意保持开放(键空间是每一个 CSS 属性,objectui 的declarations()拿到什么就 kebab 化发什么),按批 12 标准记在三处:schema JSDoc、测试 pin、账本行。二、另外五个文件 —— 22 个站点,实测没有授权门
三条独立测量(2026-08-03,均带阳性对照):
packages/spec/src里除ui/index.tsbarrel 外没有任何模块 import 它们;协议里不存在component.touch/page.dnd/app.motion这类承载键。defineStack的ObjectStackSchema做 BFS(build-schemas.ts给 authorable-surface 的 tombstone 门禁可被手编基线绕过 —— 删掉基线行就删掉了证据(#4638 / #4643 已两次这样过绿) #4650 删除检查用的同一套闭包),6849 个节点,22 个站点一个都没走到。同一次运行里三个阳性对照全部root-graph:PageSchema、批 11 的WebhookSchema、批 10 的StateMachineSchema。对照通过,所以「不可达」是关于图的事实,不是仪器坏了。.parse()。objectui 只 re-export 推断类型,并明确说不 re-export 校验器([umbrella][security] 授权全生命周期缺口地图 — 包开发 → 生产上线(P0–P3) #2561)。.strict()是 parse 的属性,而这里没有 parse。收紧它们不拦任何东西,只会花掉一次 v17 破坏性变更让文件看起来完成,并留下账本自己警告过的东西 —— 「一个被精确校验的死槽位是更有说服力的谎言」(#4583 那一行)。真正该判的是 ADR-0049 enforce-or-remove,已归档 #4988。每个文件按批 12 标准三处留痕(文件头注释 + 测试 pin + 账本行),并且 pin 是会红的:每个文件都有一条「除 barrel 外无 import 者」断言,谁给这套词汇接上承载键,那条就变红并把人指回 #4988。
三、仪器自证(每一类新断言都先证红,再信绿)
ResponsiveStyles整张别名表hideOn别名hiddenOntouch.zod加一个真实承载 importui/component.zod.tsDragConstraintSchema关上check:strictness-ledger算术其中一次破坏抓到了我自己的仪器欠缺:import 者 pin 一开始只匹配
from '…',barrel 用的是export * from,而裸副作用 import 两者都不是 —— 先红后绿这一步不做,这条 pin 会以一个部分空洞的绿落地。已改成三种形式都匹配。四、ADR-0087 示例应用验证(附一条要紧的发现)
按槽位溯源解析三个应用的构建产物(批 12 的警告:这两个形状全 optional,
{}能过,按形状匹配的走法会「找到」成千上万个无关对象、给出一个毫无意义的绿。所以只解析真实承载槽位上的值):三个应用
validate全过(exit 0,零 error)。validate上没红,这本身是个发现。 把responsiveStyles.large改成.lg注入源码后,objectstack build与validate都通过,坏键还写进了产物。查下去发现:这条路根本不按PageSchema解析页面元数据 —— 一个PageComponentSchema自 ADR-0089 D3a 起就拒绝的键同样一路通过。也就是说 #4001 各批验收里那条「三个示例应用 validate 全过」对 page 面是恒真的空证。已归档 #5000。本 PR 的阴性对照因此走真门,并且是红的:
这条「门在哪」的测量结果记进了
responsive.zod.ts的文件头 —— 收紧不该声称自己没有的触及面。五、账本
ui/三个 triage 行拆开重写;responsive.zod.ts单独成行并标 strict as of 未知键静默剥离仍是全仓默认:把 #3405 的 strict 收紧从一个 schema 推广到整个可授权面(ADR-0078 完整性闸门) #4001 批 13;五个文件合并为一行,class 由改判 no door,附完整测量。authorable (p)no door—— 账本原来的问题「这个 schema 的输入由谁写」没有「没人,因为没有 parse」这一格,而这一格只能测出来、读文件读不出来。responsive.zod.ts行删除(reverse pin:先红后删,不是凭记忆);header123 → 119,由存活行重算(29+20+14+9+7+7+6+4+4+4+3+3+2+2+2+1+1+1 = 119)。123 of 123→97 of 119。小计动了 26 而只关了 4 个站点,这 22 的差额就是本批的实际发现。DashboardWidgetSchema.responsive按断点建模 —— objectui#3173 维护者已裁决;目标 17.0.0 正式版,带回退条款 #4876 的账本冲突按预案处理:两边行都保留后重算,check:strictness-ledger判定。验证
@objectstack/spec:297 文件 / 7550 用例通过,tsc --noEmit干净(合并 origin/main 后复跑)check:*闸门全绿(8 个生成物 + 8 个源审计,含check:strictness-ledger/check:authorable-surface/check:api-surface,build 在前)lint55/1014、metadata15/336、metadata-protocol34/299 通过metadata-protocol首轮 25 个测试文件加载失败(Cannot find package '@objectstack/metadata/errors')—— 合并带进来的新 subpath 导出遇上陈旧 dist,即 AGENTS.md §9 那一类。重新构建后 34/34 通过,与本 PR 无关。git merge origin/main(未 rebase、未 force-push)→ 重装 + 重建 →check:generated全绿 → 断言兄弟条目存活(spec:DashboardWidgetSchema.responsive按断点建模 —— objectui#3173 维护者已裁决;目标 17.0.0 正式版,带回退条款 #4876 的ui/DashboardWidget:responsive [RETIRED]、批 11 的 webhook protection 信封 5 键、批 12 的 etl 键、两条 conversion 注册项、四个 changeset 全在)DashboardWidgetSchema.responsive按断点建模 —— objectui#3173 维护者已裁决;目标 17.0.0 正式版,带回退条款 #4876 的联合行为实测:dashboard.widgets[].responsive出 spec:DashboardWidgetSchema.responsive按断点建模 —— objectui#3173 维护者已裁决;目标 17.0.0 正式版,带回退条款 #4876 的墓碑处方,page.components[].responsive+.responsiveStyles正常通过 —— 存活的那个承载键归档的范围外发现(均未指派)
objectstack build/validate从不按 PageSchema 解析页面元数据:ADR-0089 D3a 早就该拒绝的键一路通过,#4001 的「三个示例应用 validate 全过」对 page 面是空证 #5000 ——objectstack build/validate从不按PageSchema解析页面元数据变更集:
.changeset/unknown-key-strictness-ui-batch13.md(major,v17 rc 窗口)。🤖 Generated with Claude Code
https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
Generated by Claude Code