Found by the os-dev seat while implementing #14402 (the ADR-0049 record for the object-scoped validation-message key). Not fixed there: #14402's diff is ruled to the governance record only, and this one lands in packages/spec source with a regenerated artifact behind it — a different gate family and a different review surface, so it is filed rather than ridden along.
Two prescriptions for the same retired key, one of them now incomplete
validationMessages was retired in 17.0.0 (#4667). Two author-facing texts tell an author what to do instead, and since 17.3.0 (#14381 / #14253) they no longer say the same thing:
packages/spec/src/system/translation.zod.ts, TRANSLATION_KEY_GUIDANCE.validationMessages — the message an author sees when the strict door rejects the retired key. It was updated and is complete: author the message on the rule, and translate it under objects.OBJECT._validations.RULE.message, which the write path resolves.
- The ADR-0087 conversion
translation-validation-messages-removed, whose description renders row translation.validationMessages of docs/protocol-upgrade-guide.md (a generated file — gen:upgrade-guide / check:upgrade-guide). It still ends at "Author the message on the rule itself (object.validations[].message)" and never names the translation route.
Everything in that row is still true. The defect is that it is the migration text — the one read by exactly the population that authored the retired key, i.e. the people who wanted their rule messages translated — and it steers them to a plain authored literal without telling them the bundle key now exists. The sibling prescription, ten metres away in the same package, does tell them.
Same class as the defect that produced #14402
#14402 exists because the 17.0.0 retirement's record outlived the fact it described. This is the milder half of that: a record that is not false, only silent about the thing its reader is looking for. content/docs/ui/translations.mdx carried the false half and is corrected by #14402's PR.
Surface
No behaviour changes; a changeset is a judgement call for whoever picks it up (the conversion id and its mechanics are untouched — only the human-readable description moves).
Generated by Claude Code
Found by the
os-devseat while implementing #14402 (the ADR-0049 record for the object-scoped validation-message key). Not fixed there: #14402's diff is ruled to the governance record only, and this one lands inpackages/specsource with a regenerated artifact behind it — a different gate family and a different review surface, so it is filed rather than ridden along.Two prescriptions for the same retired key, one of them now incomplete
validationMessageswas retired in 17.0.0 (#4667). Two author-facing texts tell an author what to do instead, and since 17.3.0 (#14381 / #14253) they no longer say the same thing:packages/spec/src/system/translation.zod.ts,TRANSLATION_KEY_GUIDANCE.validationMessages— the message an author sees when the strict door rejects the retired key. It was updated and is complete: author the message on the rule, and translate it underobjects.OBJECT._validations.RULE.message, which the write path resolves.translation-validation-messages-removed, whose description renders rowtranslation.validationMessagesofdocs/protocol-upgrade-guide.md(a generated file —gen:upgrade-guide/check:upgrade-guide). It still ends at "Author the message on the rule itself (object.validations[].message)" and never names the translation route.Everything in that row is still true. The defect is that it is the migration text — the one read by exactly the population that authored the retired key, i.e. the people who wanted their rule messages translated — and it steers them to a plain authored literal without telling them the bundle key now exists. The sibling prescription, ten metres away in the same package, does tell them.
Same class as the defect that produced #14402
#14402 exists because the 17.0.0 retirement's record outlived the fact it described. This is the milder half of that: a record that is not false, only silent about the thing its reader is looking for.
content/docs/ui/translations.mdxcarried the false half and is corrected by #14402's PR.Surface
packages/spec/src/conversions/registry.ts— the conversion'sdescription.docs/protocol-upgrade-guide.md— generated; regenerate withgen:upgrade-guide, do not hand-edit.docs/qa/platform-checklist/areas/i18n.jsonin the same pass: its clause for this key pins the prescription's content ("validationMessages cites 清空剩余 6 条 authorWarn 死键 —— book ×2 / job.id / translation.validationMessages / app.homePageId / app.areas[].order(ADR-0049,v17 限时) #4667/ADR-0049 and the rule-message home") and may want the new route naming too.No behaviour changes; a changeset is a judgement call for whoever picks it up (the conversion id and its mechanics are untouched — only the human-readable description moves).
Generated by Claude Code