Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

metadata-admin previews 仍在读取 spec 已拒收的键(AgentPreview/SkillPreview/AppPreview/DatasourcePreview),预览会为一份存不下去的草稿画出「正常」界面 #3275

Closed

Description

@xuyushun441-sys

在做 objectui#3266(把 8 个 preview 样例改成能过 ObjectStackSchema.safeParse())时,发现样例改对之后画廊反而少画了东西 —— 因为几个 preview 读的是 spec 现在明确拒收的键。这与 objectui#3236 / PR #3258 修 ToolPreview 是同一件事的其余部分:预览渲染一个保存时会被拒的键,等于告诉作者「这样写是对的」,而这正是预览存在的反面。

packages/app-shell/src/views/metadata-admin/previews/ 下,#3266 逐条实测到的:

文件 读的键 spec 现状
AgentPreview.tsx d.tools(渲染 TOOLS 芯片)、d.knowledge(渲染 KNOWLEDGE (RAG) 区块) 均为 retiredKey() 墓碑,objectstack#3894 / #3896 —— AgentSchema 按名字报错
SkillPreview.tsx d.triggerPhrases(渲染 TRIGGER PHRASES 区块) retiredKey() 墓碑,objectstack#3896
AppPreview.tsx landingRoute ?? landing ?? defaultRoute;每项 it.path ?? it.href ?? it.route ?? it.url;kind 靠 it.object/it.dashboard 推断 landing 已被 objectstack#4001 移除(替代是 homePageId);navigation 是按 type 的判别联合且每支 .strict(),根本没有 path / object / dashboard 这些键
DatasourcePreview.tsx capabilities 只认数组(Array.isArray(d.capabilities) ? … : []);driver 有 ?? d.type 回退 DatasourceSchema 是 .strict():capabilities 是对象(DatasourceCapabilities),type 直接被拒(别名提示 type → driver)

另外 SkillPreview 的 trigger-conditions 表读 cond.expression ?? cond.value,而 SkillTriggerConditionSchema 的形态是 { field, operator, value } —— 合规草稿在表里只能显示出 value 一列(实测显示成 COND | sales_order),field 和 operator 看不见。

实测到的可见后果(#3266 改样例前 → 改后,同一个画廊)

  • agent:TOOLS: query_orders / lookup_company + KNOWLEDGE (RAG): sales_playbook → TOOLS 空态、KNOWLEDGE 区块消失(样例已按裁决删键,预览无处可读)
  • skill:TRIGGER PHRASES (2) 区块 → 消失
  • app:每项下面的 /apps/crm/accounts 路径行 → 消失;Dashboard 的 kind 徽标从 dashboard 退化成 item;Landing: /apps/crm/home → Landing: /(homePageId: 'home' 没人读)
  • datasource:CAPABILITIES: read / aggregate 区块 → 消失(对象形态不被 Array.isArray 认)

也就是说:今天画廊里好看的那部分,有一截是靠不合规的样例喂出来的。

建议

按 AGENTS.md #0.1(contract-first,修生产者不修渲染器)与 #3258 的先例:

  1. 删掉对已退役键的读取路径(tools/knowledge/triggerPhrases),而不是保留;
  2. AppPreview 改为读 type 判别键 + objectName/pageName/dashboardName/url,landing 改读 homePageId(它是 nav item 的 id,不是路由字符串),路由由 shell 从元数据推导;
  3. DatasourcePreview.capabilities 改按对象渲染(展示为 true 的能力名),去掉 driver ?? d.type 回退;
  4. SkillPreview 的 trigger-conditions 表按 field / operator / value 三列渲染。

这些 ?? 回退正是 AGENTS.md #0.1 说的「宽容消费者」:它们让 AI 生成的过期元数据在设计器里看起来是对的,直到发布时才被拒。

相关

⚠️ 未指派 —— 由 #3266 顺带发现并记录(Prime Directive #10),不在那个 PR 里修:scope fence 是 apps/console,本单全在 packages/app-shell。

Activity

  1. xuyushun441-sys commented on Aug 3, 2026

    @xuyushun441-sys
    ContributorAuthor

    认领:PM 循环第 5 轮
    会话:session_01NVPjPzmmAJ2Ngtvgg5MSRa(objectui 分片 PM,账号 xuyushun441-sys)
    分支:claude/issue-3275-previews-drop-retired-keys
    Worktree:objectui-issue-3275

    分诊:无需拍板,且前置已落地

    #3266(PR #3277,已合并 03895a8f1)把样例改对了,本单是同一件事的渲染器那一半。所有键的退役裁决在上游都已完成(objectstack#3894 / #3896 / #4001 / #4158),ToolPreview 的同型修复(#3236 / PR #3258)已是现成先例 —— 照抄做法即可,没有需要维护者选的选项。

    这单的价值:今天画廊里好看的那部分,有一截是靠不合规样例喂出来的

    #3266 的浏览器实测已经把后果拍下来了:样例改对之后,agent 的 TOOLS / KNOWLEDGE 区块、skill 的 TRIGGER PHRASES、app 的路径行、datasource 的 CAPABILITIES 全部消失或退化。原因不是样例改坏了,而是这些预览读的键 spec 已经拒收 —— 预览与样例此前是"一起错"才看起来正常。

    这正是 AGENTS.md #0.1 说的宽容消费者:?? 回退让 AI 生成的过期元数据在设计器里看起来是对的,直到发布时才被拒。预览的职责恰恰相反 —— 它应该让作者当场看见自己写错了。

    派发范围(四个文件,单子已给出逐条修法)

    1. 删对已退役键的读取(AgentPreview 的 tools/knowledge、SkillPreview 的 triggerPhrases)—— 删,不是保留兜底;
    2. AppPreview:改读 type 判别键 + objectName/pageName/dashboardName/url;landing 改读 homePageId(⚠️ 它是 nav item 的 id,不是路由字符串,别当路径渲染);
    3. DatasourcePreview:capabilities 按对象渲染(展示为 true 的能力名),去掉 driver ?? d.type 回退;
    4. SkillPreview 的 trigger-conditions 表按 field / operator / value 三列渲染(现在合规草稿只能显示出 value 一列)。

    验收要求

    ⚠️ scope fence:packages/app-shell/src/views/metadata-admin/previews/。本轮同批占用 apps/console(#3276)与 .github/workflows + scripts/(#3274),另有一个 agent 在 packages/components(#3263)。


    Generated by Claude Code

  2. xuyushun441-sys commented on Aug 3, 2026

    @xuyushun441-sys
    ContributorAuthor

    PM 验收:ACCEPT — PR #3285,已入合并队列

    项 结果
    CI ✅ 14 绿 + 2 skipped,零失败(含 4 个 shard 与 Type Check)
    范围 ✅ views/metadata-admin/previews/ 内
    并入的 #3281 ✅ 一并完成,未另开 PR
    浏览器验证 ✅ 带修复截一次 + git stash 后再截一次,before→after 是实测

    它自己发现表格漏了一个文件,而且那才是症状真正的所在

    原单给了 4 行表格。它做完发现 AppNavCanvas 不在表里但必须改:画廊始终以 editing: true 渲染,于是 AppPreview 把渲染委托给 canvas —— #3266 记录的 Dashboard 徽标退化成 item、以及路径行消失,症状实际住在 canvas 里。

    这条很关键:只按表格改 AppPreview,CI 会全绿、单子会关掉,而可观测的症状一个都不会消失。它是靠浏览器验证发现表格不完整的 —— 静态改完就交,这个洞会原样留下。

    每个形状都拿装着的 spec 实跑验证,而不是照单执行

    它对每处改动都跑 ObjectStackSchema.safeParse() 核对,而不是信任 issue 正文。这在本轮已经第三次被证明是必要的(#3266 推翻了 report 的描述、#3276 多找出一个键、本单多找出一个文件)。

    一条测试工具链的陷阱,值得全仓知道

    pnpm --filter @object-ui/app-shell test -- --run <paths> 静默忽略路径过滤,加了新测试文件前后都报「20 files / 183 tests」—— 它的新测试根本没在跑。

    vitest 按仓库根解析 pattern,只有从根跑 pnpm exec vitest run packages/app-shell/... 才给真实信号 —— 换过去之后立刻抓到一个真实失败(AppPreview.test.tsx 里 getByText 命中重复元素)。

    这与本轮反复出现的主题是同一个:一个"看起来跑了"的验证等于没验证。已单独立单(见下)。

    诚实报告了一处"没有可见变化"

    validation 那一行 before→after 完全相同,它如实写明并给了理由:样例携带的是合法的 condition,所以 ?? expression 对它而言是死代码 —— 这正是 issue 的论点;改动由单元测试覆盖,而样例属 #3276 的范围。没有为了凑一个好看的 before→after 去动不该动的东西。

    ⚠️ 越界发现 #3287:v17 升级的前置阻塞项,已按跨分片协议移交

    这是本轮对 v17 最重要的一条。spec main 用 #4667/#4680 把 app.homePageId 退役为墓碑,文案写着「no shell ever read it」—— 而 objectui 的 AppContent.resolveLandingRoute() 正在读它,注释还专门解释了它存在的理由(让 CRM 示例落在 Sales Dashboard 而不是 Lead 列表)。

    墓碑的替代方案(落地页=nav 第一项)与被退役的键语义不同:退役会让所有显式设置过落地页的 app 静默改变落地位置。

    大概率是跨仓 liveness 审计的盲区 —— 消费者不在 objectstack 仓内,仓内 grep 会得出「没有消费者」。这与 objectui#3226 的形态同族(那次的结论是:当一个键的消费者在仓外时,仓内 grep 不构成"没有消费者"的证据)。

    已作为 objectstack#4865 移交主 backlog 队列(共享契约面单一 owner),并在其中建议:先核查 #4667 的 liveness 判定是怎么得出那句断言的 —— 如果只扫了 objectstack 仓,同一批退役里的其它键可能有同样的盲区,这比单个键的去留更值得先查。

    objectui#3287 已标 needs-user-decision,在上游有结论前不动那 7 处中的任何一处 —— 半改会造成预览、类型、运行时落地路由三者不一致。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions