fix(spec): app 表单摘掉八个已退役的墓碑键输入,#3786 对账门改判「真实可授权面」(#5280) - #5318
Draft
os-zhuang wants to merge 2 commits into
Draft
fix(spec): app 表单摘掉八个已退役的墓碑键输入,#3786 对账门改判「真实可授权面」(#5280)#5318os-zhuang wants to merge 2 commits into
os-zhuang wants to merge 2 commits into
Conversation
`app.form.ts` 仍在给作者渲染八个 `retiredKey()` 墓碑键的输入控件 —— `version` / `homePageId` / `objects` / `apis` / `sharing` / `embed` / `mobileNavigation` / `aria`(issue 只点了后三个,全量扫出八个)。墓碑是 `z.never().optional()`,填进去不是静默丢弃,是整条 save 硬失败并抛出该键 的退役处方。八个控件全部移除,按套件惯例在原位留注释说明能力去向。 真正的价值在门这一侧:#3786 的对账断言用 `key ∈ shape` 判定「Zod 接受该 键」。在 `retiredKey()` 出现之前这两件事同义,之后不是了 —— 墓碑**按设计** 把键留在 walked shape 里(退役套件的 liveness 行正因为键还在才保留),于是 八个墓碑键对该断言永远为真,门绿着而作者拿到 422。 谓词收紧为「∈ shape 且不是墓碑」,双向都改: - form-only 方向拆成两条独立断言,失败信息能分清「未声明→静默丢弃」与 「墓碑→硬失败」,后者更响也更早; - zod-only 方向把墓碑键排除出「必须提供或立 ledger」的集合 —— 墓碑键的唯一 正确处置就是不提供。此前 `object.fields.conditionalRequired` 不被要求回填 纯属被一条无关的 `subset` ledger 条目挡住,是运气不是设计; - ledger 的 `omit`/`subset` 自检改用 authorable 键计数,避免墓碑撑住一条 已失效的豁免。 检测器判 **schema 节点**(optional 内层是否 `z.never`),不匹配键名 —— 键名 清单本身就是 #3786 要消灭的手抄列表。这是 `build-schemas.ts` 里 JSON Schema 侧 `isRetired()`(`{ not: {} }`)的 zod 侧孪生。四条合成 schema 上的自检把 机制钉住(含 union 成员仍 live 时不算退役的安全方向),不依赖任何当期墓碑, 免得墓碑随版本退场后这条门悄悄变空转。 RED-first 实证:谓词收紧、表单未改时,`app` 那条用例红,恰好点名八个键; 摘掉输入后 41/41 绿。 表单输入变动会带走 i18n 抽取键,四个 metadata-forms bundle 按 merge 模式 重生成(纯删除 8 组);两个分区描述原文仍在宣传已退役能力(zh-CN 的 basics/navigation 甚至点名「版本」「首页」),按 bundle 值可手写的惯例一并 订正为真实语义。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ErbEDVAg1No9gdg1pgDAGB
…m-tombstone-reconciliation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 107 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
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 #5280
前提核验(origin/main @ de113a4,带阳性对照)
三条都成立,但范围比单子写的大:issue 点名三个键(
sharing/embed/mobileNavigation),按范围第 3 条全量扫下来,app.form.ts一共在提供八个retiredKey()墓碑键。另外五个(
version/homePageId/objects/apis/aria)与点名的三个同类同因:都是 17.0.0 的retiredKey()墓碑,处方都落在别的层(manifest.version;navigation首项 +isDefault;defineStack({ objects });defineStack({ apis });渲染 DOM 的组件),没有一个部分映射到 App 自身的活键,所以八个的摘除都是机械操作,按范围第 3 条「发现的一并修」同 PR 处理。1) 表单(范围 1+3)
八个
{ field: … }输入全部移除,按套件惯例在原位留注释说明能力去向。另有两个分区描述本身还在宣传已退役能力(Content的 "Objects and APIs this app uses."、Access & sharing的 "…and how it can be embedded."),一并订正为真实语义。2) 门谓词(范围 2 —— 本单真正的价值)
#3786 的断言用
key ∈ shape判「Zod accepts」。retiredKey()按设计把键留在 walked shape 里(退役套件的 liveness 行正因为键还在才保留),于是墓碑键对该断言永远为真 —— 门绿着,作者拿到 422。谓词收紧为「∈ shape 且不是墓碑」,双向都改:
object.fields.conditionalRequired没被要求回填,纯属被一条无关的subsetledger 条目挡住,是运气不是设计。omit的存在性、subset的非空性)改用 authorable 键计数,免得墓碑撑住一条已失效的豁免。检测器判 schema 节点(optional 内层是否
z.never),不匹配键名 —— 键名清单本身就是 #3786 要消灭的手抄列表。这是build-schemas.ts里 JSON Schema 侧isRetired()({ "not": {} })的 zod 侧孪生。union 取安全方向:只要有一个成员仍把该键声明为活键,就不算退役。3) RED-first 实证(方向先预测,后运行)
预测:谓词收紧、表单未改时,
app那条用例红,恰好点名八个键;其余类型与两条 nested 方向不变。实测一致:摘掉输入后
41 passed (41)。自检钉在合成 schema 上而非当期某个墓碑:墓碑会随版本退场(
retired-key.ts写的约两个大版本),锚在活墓碑上的自检要么烂尾,要么在锚被删的那一版悄悄空转 —— 一条什么都不过滤却依旧报绿的门。四条自检覆盖:墓碑留在 shape 里(即key ∈ shape为何是错谓词)、值被硬拒且带处方、按节点而非键名判定、union 成员仍 live 时不算退役。4) 全量扫(范围 3)
17 个
*.form.ts全部在册(METADATA_FORM_REGISTRY覆盖),顶层 + 手写 nested 列表一起扫。修复后:其余带墓碑的类型(
field/view/dashboard/action/agent/skill/flow)的表单没有在提供它们,本单无需改动。未删除任何墓碑,只删表单控件 —— liveness 行依赖键继续留在 shape 里。5) i18n
表单输入变动会带走抽取键,四个
*.metadata-forms.generated.ts按 merge 模式重生成(纯删除,每个 bundle 8 组 field 键)。两个分区描述的 leaf 值按「bundle 值可手写」的惯例手工订正 —— merge 模式不会用源文覆盖已有值,不改的话渲染出来的仍是旧文案(zh-CN 的 basics/navigation 甚至点名「版本」「首页」两个已退役键)。验证
vitest run src/system/metadata-form-zod-reconciliation.test.tspnpm --filter @objectstack/spec testpnpm --filter @objectstack/spec check:generatedpnpm check:i18npnpm check:i18n-coveragepnpm --filter @objectstack/spec --filter @objectstack/platform-objects typecheckpnpm --filter @objectstack/cli testpnpm --filter @objectstack/lint testpnpm --filter @objectstack/platform-objects testnode scripts/check-nul-bytes.mjs消费半径按门的调用方扫过(不是按改动的包):
METADATA_FORM_REGISTRY的消费方是packages/cli的 i18n 抽取/覆盖率、packages/lint的翻译引用校验、packages/platform-objects的 bundle,三者的测试都跑过。已
git merge origin/main(合入 #5289 / #5293 / #5296 / #5302 / #5303),生成物整体重生成而非文本合并,合并后全部门重跑并确认兄弟 PR 的条目仍在。范围外发现
content/docs/ui/apps.mdx仍在教两个已retiredKey()退役的键(version/mobileNavigation)—— 照抄「Basic Structure」示例即解析失败,而check:skill-examples结构上看不见 #5313 ——content/docs/ui/apps.mdx仍在教version与mobileNavigation两个墓碑键(含两个os:check示例块 + 属性表一行 + 整节## Mobile Navigation);照抄「Basic Structure」示例实测parses: false。check:skill-examples看不见是因为它只跑 tsc,而这两个块是无类型标注的对象字面量,never入参类型不参与推断。同类不同页已有content/docs/protocol/objectui/widget-contract.mdx的 Theme 段仍在教 #3494 已删除的density(照抄文档即构建失败) #5291。手写文档面不在本单范围内,未在本 PR 修改。🤖 Generated with Claude Code
https://claude.ai/code/session_01ErbEDVAg1No9gdg1pgDAGB
Generated by Claude Code