Repository navigation
Description
Observation, filed rather than folded in. Found while executing #15860 (the same set, a different carrier), and deliberately kept out of that PR because #15860's dispatch fenced its scope to one file.
What
content/docs/ui/translations.mdx:84-85 restates METADATA_DOCUMENT_TRANSLATORS' keys by hand:
The metadata types resolved per request are object, view, action, app,
dashboard, dataset, and page — a field's labels are translated as part of
its object document […]
main is false here today. That is exactly why it is an observation and not a bug.
Why it is still worth a card
It is a hand-written copy of a set whose own declaration carries the rule it violates:
/**
* Metadata types whose user-facing labels {@link translateMetadataDocument}
* localizes. Derived from the dispatch table — never restate it.
*/
export const TRANSLATABLE_METADATA_TYPES: ReadonlySet<string> = new Set(
Object.keys(METADATA_DOCUMENT_TRANSLATORS),
);
The repo has now paid for this shape twice on the same set — #14378 (rest-server.ts, landed as PR #15863) and #15860 (meta-plural-i18n.test.ts) — and in both cases the restatement was accurate on the day it was written and rotted when the table grew. dataset is in the sentence above precisely because someone remembered to hand-edit it when translateDataset registered (#14253); the next registration has no such guarantee.
The carrier being user-facing docs is the argument on the other side, and it is a real one: a docs reader cannot be sent to a TS dispatch table the way a code comment's reader can. So the disposition is genuinely open, which is why this is handed back rather than fixed.
Measurement, on origin/main @ bf45e62cef1
Dispatch table keys, read out of packages/spec/src/system/i18n-resolver.ts with the TypeScript AST rather than by eye:
count=7 ["view","action","object","app","dashboard","dataset","page"]
Positive control for the extractor: the same extractor, run against a scratch copy with the dataset: row deleted, reports count=6 — so the 7 is a reading that can come out otherwise, not a constant printed back.
Population scan control: the scan that found this site fires on both known carriers of the stale six-member form (packages/rest/src/meta-plural-i18n.test.ts:9 and packages/spec/src/conversions/registry.ts:3037) before #15860's PR, and its tight reading moves 14 sites to 13 across that PR — the one row that leaves being the file that PR edits. So a zero here would have been a reading, not a silence.
Two sites measured and deliberately excluded from this card
| site | why not here |
|---|---|
packages/spec/src/conversions/registry.ts:3039 |
Fenced by two prior triages: the recorded rationale for the 17.0.0 book.translations retirement, describing the set as it stood at that removal. Rewriting it would falsify a historical record. |
packages/spec/src/system/book.zod.ts:63-64 |
⭐ The schema-side twin of that same rationale, which neither prior triage named — same stale six-member enumeration, same retirement, same character. Recorded here so it is not re-discovered a fourth time. It falls under the identical fence, so the correct disposition is "do not touch"; a card of its own would only be able to say that. |
⇒ So #15860's population reading of "exactly one live site" holds for stale restatements of this set and was a floor, not a ceiling, for hand-written ones: this file is a second live carrier that happens to be correct.
⛔ Not proposed here
The repo-wide lint gate forbidding restatement. #15860 considered and rejected it, and that argument stands unrelitigated: it would need a permanent hand-written exemption list for registry.ts and book.zod.ts, i.e. the same defect class one level up.
Related
#15860 (same set, test-file header) · #14378 (same set, rest-server.ts) · #3786 (the derivation) · #14253 (registered translateDataset) · #15915 and #16169 (same shape, different sets — noted by #15860's triage, not the same population)
Activity
os-zhuang commentedon Sep 7, 2026
Triage: closing⚠️ "This one is CURRENTLY ACCURATE. All seven are named; nothing on
not planned— outside the three admission classes (#16351 /SKILL.md:354-355), on the card's own headline fact:mainis false here today."Against each class:
TRANSLATABLE_METADATA_TYPES' own docblock: "Derived from the dispatch table — never restate it." That rule is addressed to code that could derive the set. A prose page cannot derive it, and the card makes exactly that argument on the other side: "a docs reader cannot be sent to a TS dispatch table the way a code comment's reader can." ⇒ The rule does not reach this carrier, so it is not violated here.⭐ The measurement is exemplary and is the reason this closes cleanly rather than uneasily. The count of 7 was read with the TypeScript AST, ⛔ not by eye, and it carries two controls: the extractor re-run against a scratch copy with
dataset:deleted reports 6 (so 7 is a reading that can come out otherwise, not a constant printed back), and the population scan fires on both known stale carriers before #15860's PR, moving 14 → 13 across it. ⇒ A zero here would have been a reading, not a silence. That is the standard, and this card meets it.承接者: ⛔ none, and none is required — there is nothing to carry, because there is nothing wrong. This is the one closure shape where the empty fallback is not a defect in the rule.
What I am uncertain about, stated plainly: the card's real argument is prospective, and it is a good one. The repo has paid for this exact shape on this exact set twice (#14378 → PR #15863; #15860), and both restatements were accurate the day they were written.
datasetappears in this sentence only because someone hand-edited it whentranslateDatasetregistered (#14253) — ⛔ the next registration carries no such guarantee. I am closing a site that is correct today and will silently become incorrect on an event I can name. That is a real cost and I am not pretending otherwise; what makes it acceptable is that the event is discrete, cheap to detect, and hands the card back as class (a).Reopen condition (no approval needed, and it is precise):
METADATA_DOCUMENT_TRANSLATORSgains an eighth key — i.e. any newtranslateXregisters — withoutcontent/docs/ui/translations.mdx:84-85being updated in the same change. At that moment the sentence is false and this is a plain (a) defect. Anyone landing such a registration should read this card first; the AST one-liner in the card body is the check.Reversibility: fully reversible. Nothing is edited, nothing decays faster because this is closed, and the sentence's correctness is unaffected either way.
⭐ One record in this card must not be lost, which is why it is restated here rather than left in a closed body:
packages/spec/src/system/book.zod.ts:63-64is the schema-side twin ofregistry.ts:3039's 17.0.0book.translationsretirement rationale — same stale six-member enumeration, same fence, and neither of the two prior triages named it. ⇒ Its correct disposition is do not touch (it is a dated historical rationale, likeregistry.ts:3039), and it is recorded here so the next sweep does not re-discover it a fourth time and file it as new.⛔ Not proposed and ⛔ not to be revived on this card: the repo-wide lint gate forbidding restatement. #15860 considered and rejected it, and that argument stands unrelitigated — it would need a permanent hand-written exemption list for
registry.tsandbook.zod.ts, i.e. the same defect class one level up.Generated by Claude Code