feat(spec)!: 清空剩余六条 authorWarn 死键 —— book ×2 / job.id / translation.validationMessages / app.homePageId / app.areas[].order (#4667) - #4680
Merged
Conversation
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
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 107 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…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
This was referenced Aug 2, 2026
os-zhuang
marked this pull request as ready for review
August 2, 2026 17:40
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#4488 把声明本身在误导的键标为
authorWarn—— 不只是没人读,而是形状让作者合理地以为它在配置什么。#4509、#4583 清掉了其余的,这六条是剩下的,而且每一条读起来像活的理由都不一样。⏳ 为什么现在
spec 处于
17.0.0-rc.1、pre 模式仍开着。破坏性移除现在进 17.0.0,changeset pre exit之后要等 v18 —— 这六条会在整个 17.x 里继续被作者写下去。六条,和各自「读起来像活的」的原因
book.translationsbook.groups[].translationsdoc.translations两个文件之外、同名同形状、在每条 doc 渲染路径上都是活的。book 的这个图被解析、存储、往返,然后以创作语言渲染给每一个读者 —— tree endpoint 和 portal 逐字输出label/description。job.idnamewhen omitted」宣告了一个不存在的身份覆盖。name才是调度键、sys_job行键、JobExecution.jobId戳 —— 两个只有id不同的 job 是同一个 job 声明了两遍。translation.validationMessageserrors:作者直接指进来。app.homePageIdapp.areas[].orderorder是真被排序的;area 级从来不是,两个渲染器都按数组顺序迭代。os migrate meta --from 16自动改写既有源码。路线故意不统一 —— 账本纪律随之相反
retiredKey墓碑:book.groups[].translations、app.homePageId→ 账本行保留(键仍在 walked shape 里)guidance:其余四条 → 账本行删除(留着会报 ORPHAN)group 那条是全批最容易做错的一处:
BookGroupSchema是 plainz.object、没有.strict(),平删会被 zod 静默 strip —— 拿一个静默 no-op 换另一个(#2169「Mark Done 什么也没做」的形状)。退役的 alias 拼法(
i18n、home、homepage、landingpage、sort)路由到同样的处方,而不是改名到一个同样已经没了的键。顺手修掉一条指向死键的处方
#3778 当初是用「改用
validationMessages」来退役errors的 —— 那是一条指向另一个没人读的组的处方,照做只是把内容从一个死地方搬到另一个。本 PR 把它改写成指向object.validations[].message。这已经是同类第三次(#4583 的
READ_ONLY_BELONGS_ON_DATASOURCE、#4509 的mapping.guidance.skipErrors)。退役一个键之前,先 grep 有没有别的处方指着它。ADR-0087
三条新 conversion(
book-translations-removed、job-id-removed、translation-validation-messages-removed)+ 扩展app-dead-authoring-keys-removed下钻areas数组,全部接进 protocol-17 的 D3 链步。两处 grep 找不到、闸门找到的授权点
objectstack-i18nskill 在可复制示例里教validationMessages—— AI 会逐字照抄。check:skill-examples用 tsc 抓到。examples/app-todo三个 locale 都写了这个组:en的只是重复了规则自己的文案,zh-CN / ja-JP 的翻译从来没被渲染过。全量 build 抓到。测试夹具上的一点小心
order在 nav item 上是活的、只在 area 上是死的。八个order:站点我逐个核了上下文才动 —— 盲扫会退化一个真实特性。验证
pnpm build71/71、typecheck122/122、lint干净liveness/empty-state/authorable-surface/docs/api-surface/spec-changes/upgrade-guide/skill-refs/skill-docs/skill-examples/variant-docs/strictness-ledger/generated+check:i18npackages/spec7313/7313 通过;新增 16 条 pin 测试(含 group 级墓碑必须 throw 而不是被 strip、errors处方不得再提validationMessages)pnpm test131/132 —— 唯一未过的@objectstack/dogfood单独复跑 459 passed / 3 skipped。它在本容器的全量并行下会拿到 SIGTERM(上一批 feat(spec)!: 退役五个「lint 永远无法告警」的键,并接通 doc.tags (#4509) #4664 同样如此),CI 里 dogfood 是独立 job,不受影响authorWarn从 8 条降到 2 条 —— 只剩 app.areas[] 的 visible / requiredPermissions 是 fail-open 的访问闸门 —— 服务端从不走 areas(ADR-0049,v17 限时) #4651 的两个 fail-open area 闸门,那两条要的是决策不是补丁🤖 Generated with Claude Code
https://claude.ai/code/session_01E5CYr5SDwe85gH2Jr5KSgu
Generated by Claude Code