Skip to content

fix(spec): aria 墓碑不再指向同一大版本里已退休的落点 (#6756) - #6854

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-6756-aria-tombstone-dead-pointer
Aug 9, 2026
Merged

fix(spec): aria 墓碑不再指向同一大版本里已退休的落点 (#6756)#6854
os-project-manager merged 1 commit into
mainfrom
claude/issue-6756-aria-tombstone-dead-pointer

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#6756

缺陷

dashboard.widgets[].ariaretiredKey() 提示 —— 也就是升级中的作者实际收到的那个字符串 —— 声称共享的 AriaProps 形状「stays live on app.aria」。但 App.aria 自己就是一个 retiredKey() 墓碑,和它在同一个 17.0.0 里被 2026-06 app liveness 审计移除。提示把作者送向一扇不存在的门,然后在两行之后递给他们 os migrate meta --from 16 —— 而 app-dead-authoring-keys-removed 这个转换恰好会把 aria 从 app 源里剥掉。按提示操作的代价是两轮返工外加一次静默的数据丢失。

反向的一半同样是坏的:App.aria 的处方说「declare aria on the component/widget」,widget 那一半指的正是 #5010 退休掉的 dashboard.widgets[].aria。两个墓碑互相指向对方已退休的键。

实测的锚点(issue 记录的 252f71bd6 已过期,全部在 fresh mainc32944d6 上文本检索复测)

#站点复测行号
1packages/spec/src/ui/dashboard.zod.ts import 注释14-17(claim 在 15
2packages/spec/src/ui/dashboard.zod.ts 墓碑上方内联注释602-611(claim 在 610-611
3packages/spec/src/ui/dashboard.zod.tsretiredKey() guidance612-622(claim 在 619-620,migrate 句在 621
4packages/spec/src/migrations/registry.ts protocol-17 迁移记录895-896
5packages/spec/liveness/dashboard.json ledger note150
6packages/spec/src/ui/app.zod.ts 互指的一半(issue 列为 "Related, likely the same fix")1400-1408

另外两处 issue 未列、但携带同一 reciprocal 错误、由 sweep 找出并一并修正:packages/spec/liveness/app.json:253packages/spec/src/ui/app.form.ts:89-91(均为散文/注释)。

AriaProps 的真实去向(按实测,不按假设)

git grep "aria: AriaPropsSchema" -- packages/spec/src 得 25 处活声明(component 20 / page 2 / action 1 / chart 1 / view 1)。以仓库自己的 liveness ledger 为判据:

ledger 判定
page.ariapage.components[].arialive —— "ARIA attributes applied by objectui renderers"
list view 的 arialive —— "objectui: ListView.tsx applies aria-label/-describedby/-live"
action.arialive,但注明 PARTIAL(只有少数 renderer honour,核心 action 按钮/菜单不)
app.ariadead —— 即本缺陷
dashboard.ariadashboard.widgets[].aria、form view 的 ariadead
chart.aria无 ledger 行liveness/chart.json 不存在)

objectui 侧佐证:components/src/renderers/basic/elements.tsx 四处 ariaAttrs(props.aria)plugin-list/src/ListView.tsx:2041-2044plugin-detail 的 record-path / record-quick-actions。

所以处方只列举前三个无歧义的活载体。刻意不列 chart.aria:它有声明、没 ledger 行、没实测到 renderer 读 —— 把它写进「stays live on」正是在小尺度上重犯本 issue 要修的错。action.aria 的 PARTIAL 只写在注释里,不进 parse 可达的处方。

os migrate meta --from 16 的动词

该命令仍然该留 —— 转换确实覆盖这个键。但它做的是剥离不是搬迁:conversions/registry.tsdashboard-widget-action-aria-removed 调用 stripKeys(w, ['actionUrl','actionType','actionIcon','aria'], …),fixture 的 after 里 widget 已无 ariaexpectedNotices: 4。故动词由 "to rewrite it automatically" 改为 "to remove it automatically" —— 后者是仓库既有措辞(component.zod.ts:770,781),不是新造。

dashboard.mdx生成,非手写

content/docs/references/ui/dashboard.mdx:6 明写 {/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. */}。因此未手改,走 gen:docs 重新生成;app.mdx(同样生成)与 docs/protocol-upgrade-guide.mdgen:upgrade-guide)随源同步刷新。注意 issue 给的路径 content/docs/dashboard.mdx 不存在,实际是 content/docs/references/ui/dashboard.mdx

接受集合逐字节不变

改动全部是 retiredKey() 的 guidance 参数、注释、或 ledger 的 note 散文。retiredKey() 无论字符串是什么都返回 z.never({ error: () => guidance }).optional()。未触碰任何 key set / Zod 类型 / superRefine / optionality。gen:schema 独立复核:authorable-defaults/ verified — 1308 default(s) unchanged

反向验证(方向在跑之前先行预测)

预测:文本一半在还原后转红;结构一半两个方向都绿 —— 因为本 lane 的准入测试就是接受集合不变,它不允许翻转。

实测:把两个 guidance 字符串 git checkout origin/main -- 还原、测试保留修正后的期望:

× REJECTS an authored `aria` with the prescription, naming its surviving homes
× the widget tombstone still fires, and points at surfaces that survived 17.0.0
× the App.aria tombstone points at a page component, not at the retired widget surface
× rejects `aria` with its upgrade prescription
Test Files 3 failed (3)
Tests 4 failed | 150 passed (154)

四条文本断言全红,两条结构断言(really accepts / really rejects)在 150 passed 之中 —— 与预测完全一致。结构一半不是装饰:它是文本一半被比对的 ground truth,也是反空转保障

反空转单独取证:把 aria: retiredKey(…) 整条删除(不是改措辞),新 pin 依然转红,且红在预期的那一条上:

AssertionError: the widget `aria` prescription must still be reachable through the parse:
expected 'Unrecognized key(s) on this dashboard…' to contain '`dashboard.widgets[].aria` was removed'

即:措辞漂移由枚举断言接住,整条消失由这条接住。

既有断言此前把缺陷钉死 —— 重新瞄准而非删除

sweep 发现两处既有测试要求保留错误声明,这也是我最初 pin 检索漏掉的(它们写成转义正则,字面量 grep 匹配不到):

  • packages/spec/src/ui/dashboard.test.ts:588 —— expect(message).toMatch(/app\.aria/)。其注释的意图("shared shape survives elsewhere")是对的,被点名的实例是死面。已重新瞄准到活载体,并补上 not.toMatch(/app\.aria/i)
  • packages/spec/src/ui/app.test.ts:1046 —— ['aria', { label: 'x' }, 'component/widget'],期待片段正是错误的那一半。已重新瞄准到 page.components[].aria

两处都保留了原有的守护力,属 fixture triage 的「re-spell / re-aim」而非「删除」。

验证

gate结果
vitest runpackages/spec 全量)Test Files 347 passed (347) / Tests 8881 passed (8881)
pnpm --filter @objectstack/spec typecheck✅ exit 0(tsc --noEmit + check:scripts-typecheck + check:test-typecheck;新测试文件零类型错误,未进 test-typecheck-debt.json
check:liveness
check:upgrade-guideprotocol-upgrade-guide.md is up to date.
check:spec-changesspec-changes.json is up to date.
check:docs230 generated files in sync with packages/spec
scripts/check-nul-bytes.mjs✅ 6362 文件,无裸控制字节;改动文件另做 [\x00-\x08\x0b\x0c\x0e-\x1f\x7f] 自扫,无命中
scripts/check-type-check-coverage.mjsOK — 62/77 …--re-measure 需要整棵 build closure 才能跑;但 packages/spec 已在 #5286 从 TEST_DEBT 毕业,改为 test-typecheck-debt.json 的按文件棘轮(由上面的 check:test-typecheck 直接校验),故本改动无法触碰任何 TEST_DEBT 数字。

Changeset

.changeset/aria-tombstone-dead-carrier.md —— @objectstack/spec: patch。这是 parse 可达的作者可见散文(retiredKey() 的 guidance 会原样出现在解析错误里,并被 gen:docs 发布到参考文档),不是纯注释改动,所以按 patch 发版而非 skip-changeset

路由出本 lane 的发现

.changeset/dashboard-widget-action-aria-removed.md:58packages/spec/CHANGELOG.md:604packages/lint/CHANGELOG.md:295content/docs/releases/v17.mdx 同样带这句旧声明。均属历史记录(CHANGELOG 已消费,releases 按 CLAUDE.md 在代码 PR 中绝不触碰),故未改动,仅在此列出。


Generated by Claude Code

`dashboard.widgets[].aria` 的 retiredKey() 提示声称共享的 `AriaProps`
"stays live on `app.aria`",而 `App.aria` 自己就是同一个 17.0.0 里被移除的
retiredKey() 墓碑;两行之后推荐的 `os migrate meta --from 16` 恰恰会把
`aria` 从 app 源里剥掉。反向的一半同样坏:`App.aria` 让作者写到
"component/widget",widget 那一半正是 #5010 退休的 `dashboard.widgets[].aria`。
两个墓碑互指对方已退休的键。
按 liveness ledger 实测重新校准落点:page.aria / page.components[].aria /
list view 的 aria 为 live;action.aria 为 live 但 PARTIAL;chart.aria 无 ledger
行,故不列入 —— 多列一个没有渲染器读的面就是在重犯本 issue 修的错。
migrate 动词由 "rewrite it" 改为 "remove it":该转换调用 stripKeys,做的是剥离。
接受集合逐字节不变:改动全部是 retiredKey() 的 guidance 参数、注释与 ledger
的 note 散文。gen:schema 独立复核 1308 个 authorable default 未变。
两处既有断言此前把缺陷钉死(dashboard.test.ts 要求 /app\.aria/、
app.test.ts 期待 'component/widget'),已按其原意重新瞄准而非删除。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ffcE95NaMJcL9XJ9VDYgk
@vercel

vercelBot commented Aug 9, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 9, 2026 12:43am

Request Review

@github-actionsgithub-actionsBot added size/m documentation Improvements or additions to documentation tests protocol:ui tooling labels Aug 9, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

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

112 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 @objectstack/spec)
  • content/docs/kernel/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/data-service.mdx(via @objectstack/spec)
  • content/docs/kernel/runtime-services/email-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx(via @objectstack/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 @objectstack/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx(via @objectstack/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/field-grouping-and-order.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.

@os-project-manager
os-project-manager marked this pull request as ready for review August 9, 2026 01:05
@os-project-manager
os-project-manager added this pull request to the merge queueAug 9, 2026
Merged via the queue into main with commit 43a7a8dAug 9, 2026
26 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-6756-aria-tombstone-dead-pointer branch August 9, 2026 01:21
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:uisize/mteststooling

Projects

None yet

2 participants

@os-project-manager@claude