Skip to content

class (c): a dotted messages id is authorable, schema-valid and resolves to nothing — and TranslationItemSchema's own @example teaches it, at two sites #18190

Description

@claude

Surfaced by #17768's dev as a class-(c) out_of_scope_findings entry; the domain:devx seat verified two of its three legs and names the third as unverified. ⛔ Unlabelled for domain:* and ungraded — routing and grading are triage's. ⛔ The filer did not dedupe; dedupe words at the bottom.

Class (c) — authorable metadata that the runtime silently drops

A messages id containing a dot is writable, schema-valid, and resolves to nothing. Nothing refuses it at either door.

Verified by the seat

1 — messages is a FLAT record, so a dotted id is a key that merely contains a dot, ⛔ not a path:

packages/spec/src/system/translation.zod.ts:670
  messages: z.record(z.string(), z.string()).optional()
             .describe('UI message translations keyed by message ID')
control: 163 occurrences of `z.` in that file ⇒ the grep discriminates

2 — the spec's own docblock @example teaches the trap, and it does so TWICE⚠️ the dev reported one site; there are two:

packages/spec/src/system/translation.zod.ts:577    "messages": { "common.save": "Save" }
packages/spec/src/system/translation.zod.ts:1430    messages: { 'common.save': '保存' }

⭐ That is the load-bearing part. A docblock @example on the schema is the doorway an authoring agent copies from — so the trap is not merely possible, it is demonstrated to the author by the contract itself. It will keep being minted until this is fixed.

⛔ NOT verified by the seat — establish it before acting

The dev reports that "both t() implementations walk the key segment by segment, so a dotted id is unreachable". The seat did not confirm this. It looked in packages/spec/src/system/i18n-resolver.ts and found the only split('.') there (:3263) is a schema-title helper, unrelated to translation lookup — so the t() implementations are elsewhere and were not located.

⇒ ⛔ Do not treat the unreachability mechanism as measured. Find both t() implementations, show what a dotted id does at each, and say whether the two agree — if one resolves it and the other does not, that is a bigger finding than this card describes.

Corroboration already in the tree

packages/plugins/plugin-audit/src/translations/messages.ts:3-10 is reported to document this rule privately, for its own bundle — i.e. a team already hit it and wrote themselves a local note instead of the rule reaching the contract. Worth reading as evidence of the class, ⛔ not as a second measurement.

Suggested shape (⛔ a proposal, not a prescription)

Two independent halves; ⛔ do not assume one implies the other:

  1. Fix the doorway — the two @example blocks must stop demonstrating an id that cannot resolve. This is cheap and is the half that stops new instances.
  2. Decide whether the door should refuse — a single-segment constraint on messages keys would make the trap unauthorable rather than merely undocumented. ⚠️ That narrows an accept set on a published schema ⇒ it is a Clause-②: yes shape and owes the contract-review path; it is ⛔ not a drive-by addition to the docs fix.

Acceptance

  1. The t() behaviour is measured at both implementations, with a firing control (an id that does resolve).
  2. The @example blocks teach only ids that resolve, verified by running one through the real lookup rather than by eye.
  3. If the schema is narrowed, that rides its own card with a Clause-② declaration — ⛔ not folded into the example fix.

Dedupe words

messages dotted key · translation message id segment · resolveKey dot walk · TranslationItemSchema example · single-segment message id


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions