Skip to content

docs(fields,roadmap): the built-in locale count is ten, and the shipped docblock stops restating it - #9872

Merged
os-sales merged 2 commits into
mainfrom
claude/issue-9615-locale-count-ten
Sep 18, 2026
Merged

os-sales merged 2 commits into
mainfrom
claude/issue-9615-locale-count-ten

Conversation

@os-sales

Copy link
Copy Markdown
Collaborator

Fixes #9615

Clause-②: no

@object-ui/i18n ships ten built-in locale packs. Seven sites in this tree said eleven,
and one of them is published source.

The count, enumerated rather than trusted

The card states the shipped count as ten. That number was re-derived here rather than adopted:
readme-locale-count-7989.test.ts runs both published doors and asserts they agree —
BUILT_IN_LANGUAGE_CODES from the package entry, and the builtInLocales map behind the
@object-ui/i18n/locales subpath. Run at this branch's head, it passes: 4 tests, 1 file.
The codes are en zh ja ko de fr es pt ru ar. Deliberately NOT counted by listing
src/locales/*.ts: that directory holds thirteen files and three of them are not packs, which
is the very miscount this card is about — the 7989 pin says so in its own header.

My census differs from the card's, and the difference is the card's own premise moving

Re-run at my head, not adopted:

reading card measured here why
sites 9 over 3 files 7 over 2 files the 2 packages/i18n/README.md sites are already repaired
lit control exactly 3 files carry the string 2 files same cause
negative control 99 built-in locales 0 0 agrees

objectui#7989 is closed; its repair landed as e1c27e49. So what this card carries is not "seven
more besides that one" — it is the whole live population of the wrong count. The triage comment
read the same thing.

A blind spot in the instrument, reported and not swept

The census pattern matches a bare numeral followed by whitespace. Run bold-tolerant at the same
merge-base it reads 9 sites over 4 files, not 7 over 2. The two extra are
.changeset/7989-i18n-readme-locale-count.md and the 7989 pin's own docblock, both of which
write the numeral bolded and both of which describe the defect in the PAST TENSE. They are
historical record, not live claims, so they are correctly out of scope — but the card's lit
control ("exactly three files carry the string") was taken with a bold-blind instrument and
therefore under-counted its own population. Widening the census is not this card; the reading is
recorded so the next seat does not take that control as complete.

What changed

packages/fields/src/widgets/file-size-guard.ts — published source. The docblock asserted
the shared fields.file.exceedsMaxSize key was "already translated in all 11 built-in locales".
Measured, not assumed, that this actually ships: after building the package, the docblock's text
is present in dist/widgets/file-size-guard.d.ts, which is in this package's files — so the
false count went out in every tarball and is what a consumer's editor shows on hover. Positive
controls exceedsMaxSize and maxSizeError both fire in the same grep.

⭐ The number is removed, not corrected. Correcting it to ten reproduces the construct that
permitted the error, and this repository has now watched that construct recur three times over
this one fact: objectui#3351 in a changeset file, objectui#7989 in the i18n README, this one in
shipped source. The sentence now claims only what it needs — the key is translated in every
locale the package ships — and names all-locales-key-parity.test.ts as the instrument that
re-derives it. That test asserts the stronger invariant (every pack defines every en key) over
whatever the pack set is on the day it runs, so an eleventh pack makes the sentence MORE true
rather than false. There is no figure left to rot, which is AGENTS.md commandment #9 applied
rather than restated. The key is in fact present in all ten packs today, checked pack by pack
with a negative control.

⚠️ This is why no new pin is added here. The 7989 precedent pinned its README because its repair
left a corrected NUMBER in the prose; this repair leaves no number, so there is nothing for a pin
to compare. If a reviewer wants the stricter shape — a pin asserting this docblock never regains a
hardcoded count — say so and it is a small follow-up.

ROADMAP.md — six sites, prose, no new mechanism. Per the dispatch, a roadmap gets the
correct number and the arithmetic error, not a mechanism. ROADMAP.md line 632 carried the
arithmetic that manufactured the eleven: its list read (en, zh, ja, de, fr, es, ar, ru, pt, ko, + ar)
— eleven entries, ten unique, ar counted once in the list and once as the suffix. The duplicate is
removed, not merely the number corrected, so the next enumerator does not recount it. The three
sibling lines each claimed eleven while enumerating ten codes ON THE SAME LINE. Ten is already the
house convention in that document, which states "all 10 locales" at eight other sites.

No line numbers move: ROADMAP.md is 1899 lines before and after. Nothing in the tree cites a line
address into either changed file, checked both directions.

Changeset

patch on @object-ui/fields, matching objectui#7989's own patch on @object-ui/i18n for the
same class of defect on the same kind of surface. The reason is measured, not conventional: the
docblock reaches dist/*.d.ts, and dist is in this package's files, so a published byte moved.
check-changeset-presence.mjs classifies the diff the same way — "1 of them published source of a
package the release covers".

Verification

Every exit code below was captured before any pipe.

what result
vitest run packages/fields/ + the two cited i18n instruments 168 files, 2908 tests, all passed
pnpm --filter @object-ui/fields type-check exit 0 (tsc --noEmit && tsc -p tsconfig.test.json, both echoed)
@object-ui/fields dependency-closure build exit 0
check:control-bytes exit 0, 7937 files
check:new-line-citations exit 0, 0 new citations
check:changeset-claims exit 0, corpus 1 changeset
check:i18n-keys · check:i18n-drift exit 0 · exit 0, "0 en value(s) changed"
docs:check-links exit 0, 17 scan roots
check:comment-mask-corpus exit 0, residue unchanged at its ceiling
check:pending-changeset-literals · check-changeset-presence exit 0 · exit 0

The test-file arithmetic is stated because a filtered run that silently matches nothing also reads
green: packages/fields holds 166 test files, plus the 2 i18n instruments this branch's comment
now cites, which is the 168 vitest reported. Both cited instruments therefore really ran.

check:doc-snippets returned exit 2 — "could not run", which is NOT MEASURED, not a failure: it
needs a scoped 34-package build first. Narrowed away with proof rather than skipped — that gate
type-checks fenced snippets, and this diff changes none. All six edited ROADMAP.md lines are
outside code fences (checked with a fence-state walk), the changeset has zero fences, and the
TypeScript diff is comment-only: 19 changed lines, 0 of them non-comment, with a classifier proven
able to fire on a known code line.

pnpm lint is a repository-wide scan that belongs to CI. The narrowed run is declared with its three
readings: the population comes from the config's own files: ['**/*.{ts,tsx}']; the run reports
1 file, 0 errors, 0 warnings from --format json; and the invariance holds because
eslint.config.js enables no type-aware linting (no projectService, no parserOptions.project),
so a comment-only edit in one file cannot move any untouched file's verdict. The same command was
shown able to report a finding, on a control file created inside the tree and removed with cleanup
verified by observing state rather than by reading an exit code.

Acceptance notes

Out of scope, noted and NOT filed:

  • packages/i18n/src/index.ts and packages/i18n/package.json both hedge "10+" where the figure is
    exactly ten. The card excludes both on purpose and objectui#7989's ruling protects them as
    already-correct. A hedge on an exact number is a weaker defect than a wrong one. Successor: the
    next card that touches the i18n package description.
  • ROADMAP.md's locale counts stay RESTATED rather than derived. That is the dispatch's explicit
    boundary for a planning document, not an oversight. Successor: none — nothing re-derives a
    roadmap, and nothing should.
  • The plain-text census under-counts by missing bolded numerals, measured above. Successor: whoever
    next runs a figure census in this repository; the reading is recorded here rather than filed
    because the sites it newly finds are historical records that want no repair.

Generated by Claude Code, session session_01Xm4WFhEe5mwcgyqHjxR2hn.


Generated by Claude Code

…ed docblock stops restating it

`@object-ui/i18n` ships ten built-in locale packs. Seven sites in this tree
said eleven, and one of them is published source: the shared
`fields.file.exceedsMaxSize` docblock in `file-size-guard.ts` is emitted into
`dist/widgets/file-size-guard.d.ts`, which is in the package's `files` — so the
false count went out in every tarball and is what a consumer's editor shows on
hover.

`ROADMAP.md:632` carried the arithmetic that manufactured the eleven: its list
reads `(en, zh, ja, de, fr, es, ar, ru, pt, ko, + ar)` — eleven entries, ten
unique, with `ar` counted once in the list and once as the `+ ar` suffix. That
duplicate is removed, not just the number corrected, so the next enumerator
does not recount it.

In published source the number is removed rather than corrected. A restated
count is the construct that permits the error, and this repository has now
watched it recur three times over the same fact (objectui#3351 in a changeset
file, objectui#7989 in the i18n README, this one in shipped source). The
sentence now claims only what it needs — the key is translated in every locale
the package ships — and names `all-locales-key-parity.test.ts` as the
instrument that re-derives it, per AGENTS.md commandment #9. An eleventh pack
now makes that sentence more true rather than false.

`ROADMAP.md` is a planning document and stays prose: the six sites there get
the correct number and the duplicate removed, with no new mechanism.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xm4WFhEe5mwcgyqHjxR2hn
…s already spell it

The changeset quoted the removed numeral in plain text. Every other
post-mortem of this same defect in the tree — objectui#7989's changeset and
the docblock of the pin it landed — writes it bolded, and the difference is
not cosmetic: the census that finds live instances of this defect matches a
bare numeral followed by whitespace, so a plain-text quote in a historical
record registers as a live site while a bolded one does not.

Measured at the merge-base, the same census run two ways: 7 sites over 2 files
matching a bare numeral, 9 sites over 4 files once the pattern tolerates
bold. The two extra are this repository describing the defect in the past
tense, not claiming it. That blind spot is reported in the pull request rather
than fixed here — widening the census is not this card.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xm4WFhEe5mwcgyqHjxR2hn
@github-actions github-actions Bot added documentation Improvements or additions to documentation package: fields labels Sep 18, 2026
@os-sales os-sales added domain:ui objectui ui stream: fix lands on the published library or apps — objectui execution seat priority:p2 labels Sep 18, 2026 — with Claude
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3049.8 KB 3104.5 KB
Main entry chunk (gzip) 145.7 KB 350 KB
Entry file index-_BezNW1l.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.69KB 6.21KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 545.76KB 130.74KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 215.98KB 59.97KB
fields (index.js) 249.23KB 62.88KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.22KB 2.26KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 32.15KB 10.49KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.83KB 10.95KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 14.81KB 3.63KB
plugin-calendar (index.js) 49.92KB 14.22KB
plugin-charts (index.js) 71.61KB 20.05KB
plugin-chatbot (index.js) 195.35KB 46.52KB
plugin-dashboard (index.js) 131.44KB 34.65KB
plugin-designer (index.js) 215.94KB 44.33KB
plugin-detail (index.js) 253.37KB 65.90KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 136.81KB 34.17KB
plugin-gantt (index.js) 167.62KB 41.26KB
plugin-grid (index.js) 212.61KB 57.90KB
plugin-kanban (index.js) 48.10KB 14.94KB
plugin-list (index.js) 112.74KB 27.70KB
plugin-map (index.js) 21.48KB 6.99KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.41KB 11.93KB
plugin-timeline (index.js) 30.07KB 8.74KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 85.05KB 21.01KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 104.82KB 34.67KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.66KB 2.50KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 14.82KB 4.99KB
types (ai.js) 4.11KB 2.06KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.04KB 5.36KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@os-sales
os-sales marked this pull request as ready for review September 18, 2026 12:46
@os-sales
os-sales added this pull request to the merge queue Sep 18, 2026
Merged via the queue into main with commit 2e97c8c Sep 18, 2026
38 checks passed
@os-sales
os-sales deleted the claude/issue-9615-locale-count-ten branch September 18, 2026 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation domain:ui objectui ui stream: fix lands on the published library or apps — objectui execution seat package: fields priority:p2

Projects

None yet

2 participants