Skip to content

objectstack build / validate 从不按 PageSchema 解析页面元数据:ADR-0089 D3a 早就该拒绝的键一路通过,#4001 的「三个示例应用 validate 全过」对 page 面是空证 #5000

Closed

Description

@xuyushun441-sys

从 #4001 批 13 的 ADR-0087 示例应用验证步骤拆出(发现)。做阴性对照时撞到的:对照本身没能变红。

问题

objectstack build 与 objectstack validate 不会把 page 元数据按 PageSchema 解析。一个 PageComponentSchema 自 ADR-0089 D3a 起就是 .strict() 拒绝的键,原样通过两条命令,并被写进产物。

复现(origin/main + #4001 批 13 分支,2026-08-03)

往 examples/app-showcase/src/ui/pages/styling-gallery.page.ts 的一个页面组件上加一个键:

{
  id: 'styling_root', type: 'flex',
  responsiveStyles: { large: { display: 'flex' } },
  aKeyPageComponentHasRejectedSinceADR0089: 1,   // 加这一行
  ...
}

结果:

pnpm -s build     → exit 0(无任何相关报错)
pnpm -s validate  → exit 0(无任何相关报错)

而同一份组件走元数据类型注册表这条门是拒绝的:

getMetadataTypeSchema('page')!.safeParse(page)
// REJECTED — Unrecognized key(s) on this view/page schema:
//            `aKeyPageComponentHasRejectedSinceADR0089`

也就是说 PageSchema 的严格性在 MetadataManager.validate / GET /api/v1/meta / Studio 表单那条路上是生效的,唯独 CLI 的 build/validate 不走它。

为什么这条值得单独记

  1. 它让 未知键静默剥离仍是全仓默认:把 #3405 的 strict 收紧从一个 schema 推广到整个可授权面(ADR-0078 完整性闸门) #4001 的零破坏证据在 page 面上是空的。 这场战役每一批的验收里都有一条「app-showcase / app-crm / app-todo 三个示例应用 validate 全过」(feat(spec): reject unknown keys on an action param instead of stripping them (#3405) #3746 起就是这么写的)。对 object / flow / field 那些类型这条证据是实的;对 page 它恒为真,因为那条路根本不解析。批 13 收紧 ResponsiveConfigSchema / ResponsiveStylesSchema 时,阴性对照(把 responsiveStyles.large 改成 .lg)在 validate 上没变红 —— 只有在按槽位溯源解析产物的探针上、以及在 getMetadataTypeSchema('page') 这条真门上才变红。后两者是批 13 实际采用的证据。

  2. 产物会把坏值带下去。 上面那次注入之后 dist/objectstack.json 里确实带着未声明的键(587.8 KB 的 showcase 产物,build 打印 41 条 author-time warning,没有一条与之相关)。

  3. 这是 Prime Directive chore: version packages #10 的形状 —— 一条被当作闸门引用的命令,在这个类型上并不闸。

建议方向(未定,需维护者判)

无论选哪条,#4001 后续批次(ui/component.zod.ts 还有 29 个站点,view.zod.ts 还有 20 个)在写「三个示例应用 validate 全过」之前应该知道这条,否则会重复地把空证当成实证。

相关

按 AGENTS.md Prime Directive #10 归档,未指派。

Activity

  1. baozhoutao commented on Aug 5, 2026

    @baozhoutao
    Contributor

    🔒 认领:PM 循环第 1 轮(cli 车道,v17 优先)
    会话:session_01VkPSGsX9o17MsGv3Lbxu2w
    分支:claude/issue-5000-cli-validate-page-schema
    Worktree:objectstack-issue-5000
    域:domain:cli
    文件面:packages/cli/src/**(validate / build 命令及其共享元数据装载·校验路径)+ 对应测试 + changeset。只读消费 packages/spec 的 getMetadataTypeSchema,⛔ 不改 spec(spec 面归 spec 车道)。与同批 #5155(runtime dispatcher)、#5359(serve.ts)文件面不相交。

    PM 裁定(两轴分析,留否决窗口 —— 维护者可否决,不等批准):

    • os validate 本单接真门(方向 A 的 validate 半边,v17 breaking 窗口件):对每个已注册元数据类型走 getMetadataTypeSchema(type) 整体解析,拒绝带处方 —— 与写路径(MetadataManager.validate / Studio)同门。理由:①长远轴 —— 被 未知键静默剥离仍是全仓默认:把 #3405 的 strict 收紧从一个 schema 推广到整个可授权面(ADR-0078 完整性闸门) #4001 各批验收当作闸门引用的命令必须真闸(declared = enforced),否则「三个示例应用 validate 全过」对 page 面恒为空证;②防 AI 轴 —— AI 批量写元数据时,静默通过 + 产物带坏键正是错误被掩盖的温床,publish 时响亮拒绝优于消费端宽容。
    • build 侧按测量定:先测三个示例应用的红量;能在本单内修干净则 build 同样接门;若存在本单内修不完的存量违规,build 降为响亮 warning 并立后续单跟踪硬化,⛔ 不许静默通过。
    • 否决方向 C(把「不是闸门」写进文档)—— 两轴皆负:固化空证,且给 AI 留下声明与强制脱钩的先例。

    同日 churn:packages/cli 昨日被 #5314(ADR-0120 收尾)、更早被 #5065(apis: 硬拒)触及 —— dev 基于合并后代码工作,issue 引用片段以 origin/main 为准先核对。


    Generated by Claude Code

  2. baozhoutao commented on Aug 5, 2026

    @baozhoutao
    Contributor

    ✅ 验收通过 —— 前提证伪 + 证据补齐,PR #5380 转 ready 入队;本单随其合并关闭

    对 GitHub 实况复核(cli 车道 PM,session_01VkPSGsX9o17MsGv3Lbxu2w):

    前提裁定:本单描述的缺口在当前 main 上不存在。 dev 用纯对象字面量配置(绕开 definePage 即时 parse)复现本单注入键:os validate exit=1 带 ADR-0089 D3a 处方,os build exit=1 且不写产物;本单自己的阴性对照(.lg)同样红且带 Did you mean lg -> large?。逐类型测量 24 个注册类型:21 个由同一 schema 实例承载,3 个结构性差异(field/translation/view)未声明键同样被拒。三个示例应用 validate 全绿 → build 侧无存量违规,无需降级或硬化后续单。方向 A/B/C 在当前代码上已无对象 —— 按「前提失效 + 证据补齐」关闭(dev 建议 A,PM 采纳):PR #5380 的 8 条 pin 测试把「门存在」变成 CI 会红的断言,比限定 #4001 验收措辞更难被悄悄推翻;「三个示例应用 validate 全过」对 page 面自此是实证。

    PM 公开认账一处:我在认领评论里写的裁定依据「apis: 已随 #5065 从 stack schema 退役」与合并后代码不符 —— stack.zod.ts:329 仍声明 apis:,#4936 的整面拒绝已被执行器工程(#5040 E7)的逐端点门取代。dev 以 file:line 更正并按实测分类,正确;后续读者以 dev 的 PR 评论为准。

    对账用例首战立功:PR 首次 CI 即抓到 #5312 中途注册的 api 类型(设计目标场景),并顺藤发现 ApiEndpointSchema 仍是开放 z.object —— 已立 #5384(挂 #4001 子单,spec 车道),测试内给它一条诚实账本行(schema 关上时该行会红,届时是刻意的棘轮推进)。#5379(跨 entry 实例同一性)已立为 finding。

    CI 23 项零失败(changeset 按 skip-changeset 标签豁免 —— 纯测试零发布物)。PR 转 ready 挂合并队列,跟到 MERGED。


    Generated by Claude Code

  3. added a commit that references this issue on Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions