Found while implementing #5972 (per-language uniformity for the merged Loading… group). Filed unassigned, out of that card's scope: #5972 is fenced to the ten keys whose en value is byte-identically Loading…, and only 2 of these occurrences were inside that fence. #5972 is not addressed by this card and remains open on its own.
What was measured
packages/i18n/src/locales/ar.ts writes the standalone منقوص active participle two ways:
جارٍ — final yāʾ dropped, tanwīn (U+064D) on the rāʾ. The prescriptive MSA indefinite form.جاري — the yāʾ retained (U+064A). The definite/annexed form, widely used informally.
They are one word, two spellings, differing by a single code point at the end of the first word — not two translations. Counted with a Unicode-aware standalone-word match (positive and negative controls run, including the التجارية substring trap that an ASCII-boundary regex falls into):
| spelling | occurrences in ar.ts |
|---|
جارٍ (U+064D) | 92 |
جاري (U+064A) | 8 |
After PR for #5972 converged the two in-group keys (common.loading, detail.loading), the remaining 8 are all outside that group, so nothing gates them:
| key | ar value | en value |
|---|
grid.loading | جاري تحميل الشبكة… | Loading grid… |
grid.refreshing | جاري التحديث… | Refreshing… |
chart.loading | جاري تحميل الرسم البياني… | Loading chart… |
console.initializing | جاري تهيئة التطبيق… | Initializing application… |
console.loadingSteps.connecting | جاري الاتصال بمصدر البيانات | Connecting to data source |
console.loadingSteps.loadingConfig | جاري تحميل الإعدادات | Loading configuration |
console.loadingSteps.preparingWorkspace | جاري تجهيز مساحة العمل | Preparing workspace |
console.actions.retrying | جاري إعادة المحاولة… | Retrying… |
Why this is same-screen visible
console.loadingSteps.* are the three boot steps rendered as a list, and console.initializing is the heading above them — four values, all جاري. But chart.loading and grid.loading render inside a console that has already used جارٍ for dashboard.loading, list.loading, detail.loadingAttachments and console.ai.*. So the two spellings of the same word appear in one session, and on the dashboard in one viewport.
Why no gate sees it
Same blind spots #3878 documented: all-locales-key-parity compares key sets and placeholder shapes, check-i18n-call-site-keys.mjs only asks whether a key resolves, and check-i18n-en-drift.mjs fires on an en value change — the en side of all eight is untouched and always has been. Value-level orthography in a non-Latin pack is invisible to all three.
Suggested shape, if this is taken
Normalise the 8 to جارٍ (92:8 majority, and the prescriptively correct indefinite form), then widen the #5972 pin from "one rendering per language across one group" to "one spelling of this participle across the ar pack" — the same move de-quote-pairing-3876.test.ts made when its per-key list became a pack-wide rule.
⚠️ Worth an Arabic reader's confirmation before acting. The judgement that جارٍ is correct here rests on the participle being indefinite; a phrase where it is annexed would legitimately keep the yāʾ, and none of the 8 above looks annexed, but that is a reading, not a measurement.
Generated by Claude Code
Found while implementing #5972 (per-language uniformity for the merged
Loading…group). Filed unassigned, out of that card's scope: #5972 is fenced to the ten keys whoseenvalue is byte-identicallyLoading…, and only 2 of these occurrences were inside that fence. #5972 is not addressed by this card and remains open on its own.What was measured
packages/i18n/src/locales/ar.tswrites the standalone منقوص active participle two ways:جارٍ— final yāʾ dropped, tanwīn (U+064D) on the rāʾ. The prescriptive MSA indefinite form.جاري— the yāʾ retained (U+064A). The definite/annexed form, widely used informally.They are one word, two spellings, differing by a single code point at the end of the first word — not two translations. Counted with a Unicode-aware standalone-word match (positive and negative controls run, including the
التجاريةsubstring trap that an ASCII-boundary regex falls into):ar.tsجارٍ(U+064D)جاري(U+064A)After PR for #5972 converged the two in-group keys (
common.loading,detail.loading), the remaining 8 are all outside that group, so nothing gates them:grid.loadingجاري تحميل الشبكة…Loading grid…grid.refreshingجاري التحديث…Refreshing…chart.loadingجاري تحميل الرسم البياني…Loading chart…console.initializingجاري تهيئة التطبيق…Initializing application…console.loadingSteps.connectingجاري الاتصال بمصدر البياناتConnecting to data sourceconsole.loadingSteps.loadingConfigجاري تحميل الإعداداتLoading configurationconsole.loadingSteps.preparingWorkspaceجاري تجهيز مساحة العملPreparing workspaceconsole.actions.retryingجاري إعادة المحاولة…Retrying…Why this is same-screen visible
console.loadingSteps.*are the three boot steps rendered as a list, andconsole.initializingis the heading above them — four values, allجاري. Butchart.loadingandgrid.loadingrender inside a console that has already usedجارٍfordashboard.loading,list.loading,detail.loadingAttachmentsandconsole.ai.*. So the two spellings of the same word appear in one session, and on the dashboard in one viewport.Why no gate sees it
Same blind spots #3878 documented:
all-locales-key-paritycompares key sets and placeholder shapes,check-i18n-call-site-keys.mjsonly asks whether a key resolves, andcheck-i18n-en-drift.mjsfires on anenvalue change — theenside of all eight is untouched and always has been. Value-level orthography in a non-Latin pack is invisible to all three.Suggested shape, if this is taken
Normalise the 8 to
جارٍ(92:8 majority, and the prescriptively correct indefinite form), then widen the #5972 pin from "one rendering per language across one group" to "one spelling of this participle across thearpack" — the same movede-quote-pairing-3876.test.tsmade when its per-key list became a pack-wide rule.جارٍis correct here rests on the participle being indefinite; a phrase where it is annexed would legitimately keep the yāʾ, and none of the 8 above looks annexed, but that is a reading, not a measurement.Generated by Claude Code