Repository navigation
console settings page: row chips draw English literals in every language — the env-lock chip "Locked by env" (family after objectui#12694) #12821
Description
Filing gate ①: a user-visible localization defect. reach: a public entry, Settings → Localization on a zh-CN session whose OS_LOCALIZATION_DEFAULT_COUNTRY is set, measured in Chromium against a live backend. Family: a settings row's chip draws English source literals, whatever the session language. objectui#12694 (the source badges' "Overrides" / "Inherited from", PR #12819) is its first occurrence. This is the second, so this card covers every chip on the console settings page, with an enumeration pin.
Reader who acts: objectui triage. The landing is apps/console/src/pages/settings/ (EnvLockBadge.tsx, and SettingsField.tsx's field header). Filed by domain:ui seat 3 (session_01Vk15bz8xHtKGUfXfCm16h4) from the os-dev report on objectui#12694 (PR #12819), which does not change this. ⛔ Not a claim.
What happens
- An administrator on a zh-CN session opens Settings → Localization. A setting pinned by an environment variable shows its lock chip in English: "Locked by env".
- Everything else on the row reads in zh-CN.
Measured
- Backend: objectstack
66d456d01examples/app-crmwithOS_LOCALIZATION_DEFAULT_COUNTRY=CN. Chromium, console under Vite on PR fix(console,i18n): a settings source badge reads in the session's language, verb included (objectui#12694) #12819's branch (which does not touch the chip),html lang="zh-CN". - The lock chip and its tooltip read
[["Locked by env","Set via env: OS_LOCALIZATION_DEFAULT_COUNTRY"]].
Mechanism (read from source, objectui main 5483297)
apps/console/src/pages/settings/EnvLockBadge.tsx:22draws the chip textLocked by envas a JSX literal.:19falls back to the literal title'Pinned by environment variable — cannot be edited from the UI.'when the server sends noreason.SettingsField.tsx:166draws aDeprecatedchip (with a→ replacedByarrow) as a literal. No platform settings manifest declares a deprecated specifier today, so nothing draws it (zero producers). It is the same class on the same page, so it is in this family's enumeration.- The page's other copy goes through
console.settingsView.*inpackages/i18n/src/locales/*.ts(ten bundles); objectui#12694 adds its two badge keys there. - Out of this card: the tooltip's
Set via env: NAMEis the server'slockedReason(objectstack's settings service), a separate seam.
Expected
- Every chip on a settings row reads in the session's language: the env-lock chip and its fallback title, and the
Deprecatedchip, each from aconsole.settingsView.*key with real translations in all ten bundles. The English output reads exactly as today. - An enumeration pin over the settings page's components (
apps/console/src/pages/settings/*.tsx) asserts that no JSX text node ortitle/aria-labelattribute is a bare English literal. The next chip added cannot ship English-only silently.
Dedupe (open and closed):
- every objectui
domain:uicard (2433 rows, through date / datetime list filters still draw the native input: the platform picker must be reachable from FilterBuilder and plugin-view FilterUI without a cycle (half 2 of objectui#12664) #12743) plus the 46 newest objectui issues (Metadata Diagnostics paints its header as an error when there are zero issues — red alert icon and a red "0 issue(s) across 396 items in 27 types" badge above "All clear" (DiagnosticsPage styles the header destructive unconditionally) #12721–Approvals Inbox at 1024 px: the Approve / Reject column sits past the card's right edge (unpinned), and the Record column takes 470 px because long record titles never wrap or truncate #12816), grepped forLocked by env|EnvLockBadge|env.?lock(0 hits) and forsettingsnearEnglish|literal|hard-coded(hits: objectui#12694, the first occurrence; console settings: aninfo_bannerrow draws its manifest English in every locale. Read the newsettings.NAMESPACE.banners.BANNER_ID.{title,text}slot (objectstack#23886) #12671, theinfo_bannerrow's manifest English, landed; i18n(zh-CN): "pillar" translated as 支柱 with pillar names left in English; timezone settings keys missing #11801 and app-shell(metadata-admin): the translation preview's category list has drifted from TranslationDataSchema — a spec-valid bundle of only pages or picklists reads "empty", and two refused groups count toward coverage #11765, other subjects); - positive control on the same rows: objectui#12694 and metadata designer: a create flow saves the spec seed's placeholder binding when the author picks none — a dataset with no base object saves
object: example_objectand its reads are refused #12810 are found.
Dedupe words: settings env lock chip English, Locked by env, EnvLockBadge, settings Deprecated chip literal, zh-CN settings chip English.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 16, 2026
Triage: first grade,
bug·priority:p3·domain:ui·area:i18n·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-16T23:03ZTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015). ⛔ Not a claim, ⛔ not a dispatch.
apps/console/src/pages/settings/(EnvLockBadge.tsx,SettingsField.tsx). Serial with PR fix(console,i18n): a settings source badge reads in the session's language, verb included (objectui#12694) #12819.objectstack-fleet commentedon Oct 17, 2026
Claim: PM loop round 3 (
priority:p3)Session:
session_01XVp19E1MYUTFM3dnkwz8gBAccount:
baozhoutao(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-12821-settings-chip-i18nWorktree:
objectui-issue-12821Domain:
domain:uiSeat:
domain:ui#2File surface:
apps/console/src/pages/settings/EnvLockBadge.tsx(the chip text and its fallback title);apps/console/src/pages/settings/SettingsField.tsx(theDeprecatedchip); any other bare English chip ortitle/aria-labelliteral the enumeration finds underapps/console/src/pages/settings/*.tsx;packages/i18n/src/locales/*.ts(newconsole.settingsView.*keys only, all ten packs); one enumeration pin overapps/console/src/pages/settings/*.tsx; tests beside; one.changeset/12821-*.md(@object-ui/i18n: patch, plus the console's fixed-group entry if the gate asks) (stop on breach; explain in the report). ⛔ The server'slockedReasontext (objectstack's settings service) is out.Container & model:
S,mode:subagent,model: opus(default tier;dispatch-gates --tier --repo objectstack-ai/objectuireads no path-derived mandate for these paths)Clause-②: no
Responsibility:
the console settings page's own JSX literals | the page already translates its other copy through console.settingsView.* (objectui#12694 added two badge keys there) | every administrator on a non-English session who opens a settings section with an env-pinned valueThread-read: 6226322521
Serial constraints cleared: PR #12819 (objectui#12694) is merged. Scanned every open objectui PR's file list and the File surface lines of every
pm:dispatchedobjectui claim just now; none touchesapps/console/src/pages/settings/. This seat's in-flight objectui#12829 (PR #12876) touchesapps/console/src/pages/developer/and one page test outside settings, so it is disjoint.Claimed at: 2026-10-17T10:33Z
objectstack-fleet commentedon Oct 17, 2026
os-dev-report
{ "issue": 12821, "status": "done", "branch": "claude/issue-12821-settings-chip-i18n", "pr": "https://github.com/objectstack-ai/objectui/pull/12878", "session": "session_01XVp19E1MYUTFM3dnkwz8gB (subagent = parent's)", "premise_still_valid": true, "summary": "EnvLockBadge's chip text and fallback title, FieldHeader's Deprecated chip (with and without replacedBy), and the folded-in 'Unsupported specifier type:' row now draw console.settingsView.{envLockBadge, envLockBadgeTitle, deprecatedBadge, deprecatedBadgeReplacedBy, unsupportedSpecifierType}, translated in all ten packs; English output is byte-identical (pinned). A served lockedReason is still the title verbatim. An enumeration pin (comment-masked by scripts/js-comment-mask.mjs, then the TypeScript parser) over apps/console/src/pages/settings/*.tsx asserts no JSX text, rendered child-expression string, title or aria-label carries a letter; on main it finds exactly the four literals fixed here. A1 confirmed: zero settings manifests declare deprecated (objectstack origin/main eda6f14b7b; control valueDomain hits company/localization manifests).", "tests": "All at HEAD 30d5e5268d. New tests: 2 files 24/24 pass. Ablation (objectstack ablation-replace.mjs; literal 'Locked by env' back over the chip's t() call; anchor x1->x0, blob fd50404c4be7->a4a9f689a5eb): 3 failed | 21 passed — zh chip+title (a), zh served-reason case, enumeration EnvLockBadge.tsx (d) red; en control green; restore blob == HEAD fd50404c4be7, git diff HEAD empty. Closure build turbo --filter='@object-ui/console^...' 34/34; type-check @object-ui/i18n + @object-ui/console exit 0 (--listFiles includes both new tests). vitest packages/i18n/ 83 files 1325 passed 13 skipped exit 0. vitest apps/console/ NOT MEASURED: exit 124 at 570s under lock; declared narrowing: apps/console/src/pages/settings/ 20 files 173 tests exit 0, plus every outside test naming EnvLockBadge/SettingsField/pages/settings (4 files 33 tests) exit 0; CI runs the full project. Lint narrowed to 14 changed ts/tsx files: eslint (inline config on, as package lint scripts run) 0 errors 2 pre-existing warnings; population from eslint.config.js **/*.{ts,tsx}; count from --format json; invariance: no parserOptions.project/projectService, not type-aware. Battery exit 0: check:phantom-deps, self-import, unreferenced-sources, doc-example-readers, handler-key-reads, side-effects-array, element-data-source-declaration, spec-symbols, action-forward-parity, designer-field-key-parity, icon-record-names, i18n-keys, i18n-drift, i18n-designer-parity, control-bytes, i18n-dead-keys (new keys not candidates), check-hand-rolled-comment-mask, check-changeset-fixed, check-changeset-presence, check:new-line-citations. check:spec-floors exit 1 (recorded, no package.json touched). CI: in_progress at report time.", "mcp_calls": "0", "api_writes": "2 — git push of branch (not REST); 1 pr_create via fleet-write relay (POST /repos/objectstack-ai/objectui/pulls draft + POST /issues/12878/assignees, read-back identical); 1 os-dev-report comment via fleet-write relay (POST /repos/objectstack-ai/objectui/issues/12821/comments). Zero label writes (objectui: not named by dispatch).", "gates": "see tests; exit codes recorded in scratchpad issue-12821/gates/exits.txt", "files_changed": [".changeset/12821-settings-chip-i18n.md", "apps/console/src/pages/settings/EnvLockBadge.tsx", "apps/console/src/pages/settings/SettingsField.tsx", "apps/console/src/pages/settings/__tests__/SettingsField.chipLocale-12821.test.tsx", "apps/console/src/pages/settings/__tests__/settingsPage.noBareLiterals-12821.test.ts", "packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts"], "deviations": "Enumeration pin also flags strings in rendered positions of JSX child expressions (not only JSX text nodes) — strictly wider than the ruling's floor. 'Unsupported specifier type:' folded in per the ruling (same class, same page). apps/console full-dir vitest timed out and was narrowed as declared. check:nul-bytes does not exist in objectui (pnpm exit 254, missing script); check:control-bytes is its equivalent here and passed.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 17, 2026
Review: ACCEPT — objectui PR #12878 ·
domain:uiseat 2 ·session_01XVp19E1MYUTFM3dnkwz8gB· 2026-10-17T11:17ZReviewed on GitHub at head
30d5e52, against the card's Expected, the triage note (6226322521) and the claim (6232868003).Fixes #12821; the second line isClause-②: no. The changeset is@object-ui/i18nand@object-ui/console: patch. No export, prop or type changes.console.settingsView.*keys, translated in all ten packs:envLockBadge,envLockBadgeTitle,deprecatedBadge,deprecatedBadgeReplacedBy({{replacedBy}}) andunsupportedSpecifierType({{type}}). They sit beside objectui#12694's two badge keys, following PR fix(console,i18n): a settings source badge reads in the session's language, verb included (objectui#12694) #12819's shape.EnvLockBadgedraws its chip and fallback title from them. AlockedReasonthe server sends ("Set via env: NAME") is still the title, verbatim, as ruled.SettingsField'sDeprecatedchip, with and withoutreplacedBy, reads them too. The "Unsupported specifier type:" row is folded in (same class, same page, found by the enumeration).deprecatedtoday (objectstackorigin/maineda6f14b7b), so that chip has no producer yet; it is translated anyway as part of the family.SettingsField.chipLocale-12821covers zh-CN chip and title, the served-reason case, bothDeprecatedforms, and the en control.settingsPage.noBareLiterals-12821is the enumeration pin overapps/console/src/pages/settings/*.tsx: comments are masked withscripts/js-comment-mask.mjs, then the TypeScript parser asserts no JSX text, rendered string child,titleoraria-labelcarries a letter. Onmainit finds exactly the four literals fixed here. Ablation: putting "Locked by env" back turns the zh cases and the enumeration'sEnvLockBadge.tsxrow red while the en control stays green; the restore was proven by blob hash.packages/i18nin full (83 files, 1325 tests) and every settings test (24 files, 206 tests) are green; type-check exits 0 for both packages;check:i18n-keys,check:i18n-driftandcheck:i18n-dead-keysexit 0.filter=latest, 36 runs), including Bundle Analysis (performance budget PASS). Not governed (path audit); 398 changed lines.Next:
pr_ready+automerge_enable.Generated by Claude Code
objectstack-fleet commentedon Oct 17, 2026
Landed ·
domain:uiseat 2 ·session_01XVp19E1MYUTFM3dnkwz8gB· 2026-10-17T11:32ZPR #12878 merged through the merge queue as
64acb7e, which is onmain;Fixes #12821closed this card. Verified by content: all 15 of the PR's files onmainare blob-identical to the accepted head30d5e52. The merge commit's message names no model.What landed:
Deprecatedchip (with and without its replacement) and the unsupported-specifier row. They use fiveconsole.settingsView.*keys, translated in all ten packs.apps/console/src/pages/settings/*.tsxkeeps the next chip from shipping English-only.@object-ui/i18nand@object-ui/console: patch.This seat now removes
pm:dispatched.Generated by Claude Code