Skip to content

feat(spec)!: 清空剩余六条 authorWarn 死键 —— book ×2 / job.id / translation.validationMessages / app.homePageId / app.areas[].order (#4667) - #4680

Merged
os-zhuang merged 3 commits into
mainfrom
claude/auth-gate-disconnect-issues-6wz8ew
Aug 2, 2026
Merged

feat(spec)!: 清空剩余六条 authorWarn 死键 —— book ×2 / job.id / translation.validationMessages / app.homePageId / app.areas[].order (#4667)#4680
os-zhuang merged 3 commits into
mainfrom
claude/auth-gate-disconnect-issues-6wz8ew

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

#4488声明本身在误导的键标为 authorWarn —— 不只是没人读,而是形状让作者合理地以为它在配置什么。#4509#4583 清掉了其余的,这六条是剩下的,而且每一条读起来像活的理由都不一样

⏳ 为什么现在

spec 处于 17.0.0-rc.1、pre 模式仍开着。破坏性移除现在进 17.0.0,changeset pre exit 之后要等 v18 —— 这六条会在整个 17.x 里继续被作者写下去。

六条,和各自「读起来像活的」的原因

为什么骗人
book.translations
book.groups[].translations
邻接doc.translations 两个文件之外、同名同形状、在每条 doc 渲染路径上都是活的。book 的这个图被解析、存储、往返,然后以创作语言渲染给每一个读者 —— tree endpoint 和 portal 逐字输出 label/description
job.id 它自己的 describe()。「defaults to name when omitted」宣告了一个不存在的身份覆盖。name 才是调度键、sys_job 行键、JobExecution.jobId 戳 —— 两个只有 id 不同的 job 是同一个 job 声明了两遍。
translation.validationMessages 平台自己的签名,两次。schema 示例给了具体覆盖,#3778 的迁移表把退役的 errors: 作者直接指进来。
app.homePageId 它自己的对冲。「if not set, usually defaults to the first navigation item」描述的就是唯一存在的行为。
app.areas[].order 能用的那个兄弟。nav 项的 order 是真被排序的;area 级从来不是,两个渲染器都按数组顺序迭代。

os migrate meta --from 16 自动改写既有源码。

路线故意不统一 —— 账本纪律随之相反

  • retiredKey 墓碑book.groups[].translationsapp.homePageId → 账本行保留(键仍在 walked shape 里)
  • strict 删除 + guidance:其余四条 → 账本行删除(留着会报 ORPHAN)

group 那条是全批最容易做错的一处:BookGroupSchema 是 plain z.object没有 .strict(),平删会被 zod 静默 strip —— 拿一个静默 no-op 换另一个(#2169「Mark Done 什么也没做」的形状)。

退役的 alias 拼法(i18nhomehomepagelandingpagesort)路由到同样的处方,而不是改名到一个同样已经没了的键。

顺手修掉一条指向死键的处方

#3778 当初是用「改用 validationMessages」来退役 errors 的 —— 那是一条指向另一个没人读的组的处方,照做只是把内容从一个死地方搬到另一个。本 PR 把它改写成指向 object.validations[].message

这已经是同类第三次(#4583READ_ONLY_BELONGS_ON_DATASOURCE#4509mapping.guidance.skipErrors)。退役一个键之前,先 grep 有没有别的处方指着它。

ADR-0087

三条新 conversion(book-translations-removedjob-id-removedtranslation-validation-messages-removed)+ 扩展 app-dead-authoring-keys-removed 下钻 areas 数组,全部接进 protocol-17 的 D3 链步。

两处 grep 找不到、闸门找到的授权点

  1. 发布的 objectstack-i18n skill 在可复制示例里教 validationMessages —— AI 会逐字照抄。check:skill-examples 用 tsc 抓到。
  2. examples/app-todo 三个 locale 都写了这个组:en 的只是重复了规则自己的文案,zh-CN / ja-JP 的翻译从来没被渲染过。全量 build 抓到。

测试夹具上的一点小心

order 在 nav item 上是活的、只在 area 上是死的。八个 order: 站点我逐个核了上下文才动 —— 盲扫会退化一个真实特性。

验证

🤖 Generated with Claude Code

https://claude.ai/code/session_01E5CYr5SDwe85gH2Jr5KSgu


Generated by Claude Code

claude added 2 commits August 2, 2026 15:44
The #4488 liveness audit flagged as `authorWarn` the keys whose DECLARATION
actively misleads — not merely unread, but shaped so an author reasonably
concludes they configure something. #4509 and #4583 cleared the rest; these six
are what remained, and each read alive for its own reason:

  book.translations               proximity — `doc.translations`, two files
  book.groups[].translations      over, same name and shape, works on every
                                  read path. These were parsed, stored and
                                  round-tripped, and rendered in the authoring
                                  locale to every reader.
  job.id                          its own describe(): "defaults to `name` when
                                  omitted" advertised an identity override that
                                  does not exist. `name` is the scheduling key,
                                  the sys_job row key and the JobExecution.jobId
                                  stamp — two jobs differing only in `id` were
                                  one job declared twice.
  translation.validationMessages  the platform's own signposts, twice: the
                                  schema example showed a concrete override, and
                                  #3778's migration table steered retired
                                  `errors:` authors straight into it.
  app.homePageId                  its own hedge: "if not set, usually defaults
                                  to the first navigation item" described the
                                  only behaviour there was.
  app.areas[].order               the sibling that works — nav-item `order` IS
                                  sorted; area order never was, and both
                                  renderers iterate the array as authored.

Routes differ deliberately, and so does the ledger discipline that follows from
them. `book.groups[].translations` and `app.homePageId` are TOMBSTONED
(`retiredKey`: `never` at compile time, the prescription at parse time) and keep
their ledger rows, because the key stays in the walked shape. The group schema
is the reason: it is a plain `z.object` with no `.strict()`, where a bare delete
would have zod silently strip the key — trading one silent no-op for another.
The other four are strict deletions carrying `guidance`, and their rows are
deleted. Retired alias spellings (`i18n`, `home`, `homepage`, `landingpage`,
`sort`) route to the same prescriptions rather than renaming onto keys that are
themselves gone.

#3778's `errors` guidance is rewritten here rather than left alone: it had been
retiring one dead key by pointing authors at another, so taking its advice moved
content from one unread group to a second one. Third instance of this shape
after `READ_ONLY_BELONGS_ON_DATASOURCE` (#4583) and `mapping.guidance.skipErrors`
(#4509) — grep for prescriptions naming a key before you retire it.

ADR-0087: three new conversions (`book-translations-removed`, `job-id-removed`,
`translation-validation-messages-removed`) plus an extension of
`app-dead-authoring-keys-removed` to drill the `areas` array; all wired into the
protocol-17 D3 chain step.

Two authoring sites the gates found that a grep would not have:
the published `objectstack-i18n` skill taught `validationMessages` in a
copy-paste example (an AI reproduces that verbatim — caught by tsc via
check:skill-examples), and `examples/app-todo` authored the group in three
locales, where the `en` entries merely duplicated the rule's own text and the
zh-CN / ja-JP translations had never once been rendered.

Care taken in the test fixtures: `order` is live on navigation items and dead
only on areas, so each of the eight sites was classified by context before
touching it — a blind sweep would have regressed a real feature.

After this the only `authorWarn` keys left are the two fail-open area gates in
#4651, which need a decision rather than a patch.

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

vercel Bot commented Aug 2, 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 2, 2026 4:44pm

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation protocol:system tests protocol:ui tooling labels Aug 2, 2026
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

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

107 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 packages/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/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/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/kernel/runtime-capabilities.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/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.

@github-actions github-actions Bot added the size/l label Aug 2, 2026
…ys (#4667)

The generated `content/docs/references/**` pages regenerate themselves; these
six sites are hand-written and had to be read.

- `ui/apps.mdx` documented `homePageId` in the property table, named it in the
  prose explaining why nav `id` is required, and authored it in the worked
  example. The same table also still advertised `objects`, `apis` and
  `mobileNavigation` — three keys #4142 retired, whose rows had outlived them.
  All four rows go; leaving a table that documents keys the schema now rejects
  is the docs half of the same defect this campaign exists to remove.
- `ui/translations.mdx` had already noticed the problem — it listed
  `validationMessages` under "Current boundaries" as having no runtime consumer
  — but described it as a gap to be filled rather than a key to stop writing.
  Rewritten to point at `object.validations[].message`.
- `protocol/kernel/i18n-standard.mdx` authored the group in its worked bundle
  and named it in the coverage-checking prose.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E5CYr5SDwe85gH2Jr5KSgu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants