Skip to content

feat(spec): 登记 ADR-0087 D2 conversion page-header-subtitle-alias(descriptionsubtitle) - #5509

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-4827-page-header-subtitle-conversion
Aug 5, 2026
Merged

feat(spec): 登记 ADR-0087 D2 conversion page-header-subtitle-alias(descriptionsubtitle)#5509
os-zhuang merged 1 commit into
mainfrom
claude/issue-4827-page-header-subtitle-conversion

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #4827
Unblocks objectstack-ai/objectui#3226

做了什么

按 ADR-0087 D2 登记 protocol 17 的 live window 条目 page-header-subtitle-alias:加载期把 page-header 节点 properties 上的 description 改写为 canonical 的 subtitle,每次改写发一条结构化 ConversionNotice。落地后 objectui 才能删掉 PageHeader.tsx 里的裸 subtitle ?? description(PD #12)。

  • packages/spec/src/conversions/walk.ts — 新增 mapPageComponents(copy-on-write,region 级)。pages[].regions[].components[] 之前没有共享 walker,protocol-15 的 page-component-visibility-to-visibleWhen 是就地展开的;新 walker 只被本条目使用,没有改动那条已发布的条目。
  • packages/spec/src/conversions/registry.ts — 条目 + fixture。
  • packages/spec/src/migrations/registry.ts — 登记进 D3 链 step 17(否则 chain-replay gate 直接红)。
  • 重生成 spec-changes.json + docs/protocol-upgrade-guide.md(guide 里这行显示 live — protocol 17 loader accepts the old shape,即预期的姿态)。
  • changeset(minor,含 FROM → TO)。

两个需要 reviewer 过目的判断

1. 两种拼写都转,但不改写 type 匹配 page-header(objectui kebab 遗留别名)与 page:header(协议 canonical 类型)两种节点 —— 后者今天写 description直接被丢在地上(canonical 渲染器只读 subtitle),同一个缺陷换个拼写而已,而 PageComponentSchema.typez.union([PageComponentType, z.string()]),两种拼写都能进到加载路径。本条目page-header 改写成 page:header:别名注册的存废是 objectui 的事,而且在开放命名空间上改写 type 正是 flow-node-http-callout-rename 要配冲突守卫的那一类动作。

2. 胜负语义照抄惯例,没有发明。 subtitle 已在场时不改写、不发通知、被遮蔽的 description 原样留下 —— 就是 renameKey 编码的房规,与 flow-node-crud-object-alias 的 fixture 注释一字不差(canonical already present → the shadowed alias is left alone)。另外只动 header 节点:description 在同层其他组件上是活的已声明属性(element:text_input 的辅助文本),fixture 里留了这个反向对照。

没有 schema 键被移除(description 从未在 PageHeaderProps 上声明过),所以不需要 tombstone,check:authorable-surface 也保持绿。

先证红(方向在跑之前就写下了)

两个场景分开做,因为它们证明的不是同一件事:

场景 A —— 摘掉注册(从 CONVERSIONS_BY_MAJOR[17] 移除,实现还在):6 红 —— D3 两条 registry-integrity(every step references only real conversion idsa graduated conversion belongs to the step for its own major)+ 我这 11 条里的 4 条;check:spec-changes 也红。测试总数 177 → 175:逐条 fixture 测试与 chain-replay 测试是 for (const conversion of ALL_CONVERSIONS) 驱动的,条目一摘它们直接消失而不是变红 —— 典型的「因为什么都没产生所以绿」,它们不是本次的见证者。

场景 B —— 掏空 apply()(注册留着):6 红 —— fixture pair + chain-replay + 我那 4 条断言改写的;总数仍是 177。但 check:spec-changes 保持绿:登记完整性 gate 钉的是「这条记录在不在」,不是「它干不干活」。两个 gate 家族各管一半,谁也替代不了谁。

一处预测报错、如实记下:场景 A 我原本预测「我加的 11 条全红」,实测只红了 4 条。另外 7 条是「什么都没发生」型断言(不改 type、遮蔽时不动、幂等、copy-on-write)与两条独立的 schema pin —— 规则死掉时它们照样绿。它们是守卫,不是见证者,这个区分不该被模板抹平。

验证

pnpm --filter @objectstack/spec test        →  311 files / 7964 tests passed
pnpm --filter @objectstack/spec typecheck   →  clean
pnpm --filter @objectstack/spec check:generated → 9/9(重生成后)
pnpm --filter @objectstack/lint test -- page →  58 files / 1225 tests passed
node scripts/check-nul-bytes.mjs            →  OK

按消费半径(而非改动包)扫了 fixture:全仓 grep page:header / page-header,没有任何 fixture 让 header 节点带 description,所以这条新规则不会把别的包的 fixture 判红 —— 与 issue 里「仓内零命中」的事实一致。

⚠️ packages/lint 首跑 10 个文件红,是新 worktree 里 @objectstack/formula / @objectstack/sdui-parser 没构建(AGENTS.md §9 的陈旧产物陷阱),pnpm --filter '@objectstack/lint^...' build 之后全绿,与本改动无关。

一处顺带记录(不在本 PR 修)

本条目的 surfacepage.component.page-header.description,叶名 description 因此进入了 build-schemas.ts 检查 (b) 的匹配词表 —— 那个检查按叶名 endsWith 匹配,所以此后任何 X:description 键被 tombstone 时都会被判为「已登记迁移」。这正是 #4659 记录的既有缺陷(不是本 PR 引入的机制),已在该 issue 下留言登记,没有另开重复单。


Generated by Claude Code

…as` (#4827)

page-header 节点 `properties.description` → canonical `subtitle`,protocol 17
live window。objectui 的 kebab 遗留别名与协议 canonical 键对同一个「页面副标题」
概念声明了两套 authorable 拼写,消费端用裸 `subtitle ?? description` 兜底
(PD #12)。不能走直接删路线:该别名的全部理由是仓外消费者 schema,删读会静默
丢副标题。改为在加载期改写,declared / loud / tested / expiring。

- `mapPageComponents` 加入 `conversions/walk.ts`(copy-on-write,region 级)
- 条目 + fixture 落 `conversions/registry.ts`,并登记进 D3 链 step 17
- 覆盖 kebab `page-header` 与 canonical `page:header` 两种拼写;不改写 type
- canonical 已在场时不改写、不发通知(照 `flow-node-crud-object-alias` 惯例)
- 重生成 spec-changes.json / protocol-upgrade-guide.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018fxLGQdatPbBUvCgiVxg6D
@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 5, 2026 2:36pm

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling size/m labels Aug 5, 2026
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec.

109 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/spec)
  • content/docs/deployment/tenancy-modes.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/apps.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

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

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[移交自 objectui] 登记 ADR-0087 D2 conversion 条目 page-header-subtitle-alias(descriptionsubtitle)

2 participants