You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Oct 26, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Oct 26, 2026. It is now read-only.
Studio: a Chinese display name derives no identifier — New Package leaves Package ID and namespace empty, New Object leaves 标识 empty, and Add Field names the field field_10 #13389
Found while building a small app end to end in Studio (zh-CN UI), on objectui main @ 6fb31dc against objectstack main @ b9c7a8f.
Steps and observations
Studio → 新建软件包(可写基座). Type 体验评审 as 显示名称. 软件包 ID and 对象命名空间 stay empty (their help text says they are filled from the display name until edited). Typing Review Lab instead fills com.default.review-lab / review_lab at once.
In the new package → 新建对象. Type 反馈 as 对象名称: 标识 stays empty. Feedback fills feedback.
On the object → 添加字段, display name 满意度, type 评分 → 创建. The field is created with API name field_10, visible in the field inspector and later in the publish diff (+ 满意度 field_10) and in the list view column picker.
Why it matters
The console is localized for zh-CN, so a Chinese author naturally types Chinese labels. Today that author gets either a blank required identifier with no hint about why it did not fill in, or an identifier like field_10 that is permanent once published (it becomes the column name and the API field everyone integrates against).
Suggested direction
Any of these would fix the experience; they are not exclusive:
derive a slug from a transliteration when the label has no ASCII letters (the platform already ships pinyin support for search, PinyinSearchPlugin on the server);
when no slug can be derived, say so next to the identifier field ("请填写英文标识" style) instead of leaving it silently blank;
never mint a positional name like field_N without showing the author that it happened and inviting a rename before the first publish.
Also seen on the same dialog: the default package id prefix is com.default., which is unlikely to be what anyone wants to ship; a prompt for the org's reverse-domain prefix would avoid it.
Triage: lands in Studio's identifier derivation for New Package, New Object and Add Field (app-shell metadata-admin); rationale: a CJK display name derives nothing (blank required id, silently) or a positional field_N that becomes a permanent API name at publish. At minimum say so beside the identifier and never mint field_N without inviting a rename; transliteration is the fuller fix.
Path: studio · 不写代码建对象、字段 | studio-authoring.object-designer-roundtrip (P1, "identifiers derive…") | step ①
Grade: priority:p2 — P1 bound from the item; a tax (the author can type an id), not a wall, so one step under.
Type: Bug
Dedupe: objectui search "Chinese display name identifier slug field_N pinyin" → no other hit.
Session: session_01AkmasAfXt3cu83xGzkuKhe (objectstack triage, run on the maintainer's request in the project thread)
Claim: card thread · domain:ui seat 1 (seat post #5560, project run by the Sales account) · 2026-10-23T18:19Z
Session: session_013zcUBV3ha3FeGmd9mV3Zza (a card thread of the project that runs domain:ui seat 1, dispatched by its coordinator; 由Sales账户的项目负责)
Account: os-sales (the seat's linked user; the card's assignee from this stroke)
Branch: claude/issue-13389-cjk-identifier
Worktree: objectui-issue-13389
Domain: domain:ui
Seat: domain:ui#1
File surface: packages/app-shell/src/views/studio-design/CreateItemDialog.tsx (New Object and the other Studio create dialogs), packages/app-shell/src/views/metadata-admin/PackageFormDialog.tsx (New Package id and namespace lines), packages/app-shell/src/views/studio-design/AddFieldPopover.tsx, packages/app-shell/src/views/studio-design/ObjectFormDesigner.tsx and packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (Add field's api name), packages/app-shell/src/views/metadata-admin/i18n.ts and the shipped locale packs (new strings), the tests of each, .changeset/ (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default judgment tier (dispatch-gates --tier --repo objectstack-ai/objectui names no path-derived mandate for this surface), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: objectui Studio's own create forms derive the identifier client side (toFieldNameLoose, toIdSegment), drop every non-Latin letter, and say nothing; no platform path covers it (the spec only states the identifier alphabet); every zh-CN author who types a Chinese label reaches it today
Thread-read: 6370409677
Serial constraints cleared: open objectui PRs read at claim time are #13395 (core ActionRunner), #13362, #13360, #13358 (workflows), #13289 (release), #13028 (timings data), #11845, #11844 (dependencies); none touches these paths. Open claims in this lane: #13384 (ActionRunner), #13350, objectstack-ai/objectstack#25936, #13348 (CI); none names these files.
Plan, stated so the review can hold it to it. Two parts:
Part 1 (this PR, needed whichever way part 2 goes, since kana, Hangul, Arabic and other scripts derive nothing even with a transliteration): when a display name is filled in but yields no identifier, each surface says so beside the identifier and asks for one typed in Latin letters, instead of the "filled in from the display name" line or silence. Add field no longer mints a positional field_N: when the label yields no api name, or yields one another field already holds, the popover shows an API name box the author fills before Create. A Latin label behaves as today.
Part 2 (transliteration of Chinese labels into a pinyin slug) is a product choice (a new client dependency and an identifier rule authors will see); it goes to the maintainer through the project's ruling flow and is not built before a ruling. Part 1's PR says Refs, not Fixes, until that ruling says whether part 2 is wanted.
Out of this card's code: the com.default. package id prefix the card mentions is the active organization's slug (default on a fresh deployment); it is noted in the report, not changed here.
{
"issue": 13389,
"status": "done",
"branch": "claude/issue-13389-cjk-identifier",
"pr": "https://github.com/objectstack-ai/objectui/pull/13414",
"session": "session_013zcUBV3ha3FeGmd9mV3Zza",
"premise_still_valid": true,
"summary": "Part 1 of the card, one PR, head 2c1247f, Refs objectstack-ai/objectui#13389 (part 1), not Fixes. (1) CreateItemDialog: a display name that derives no identifier, with none typed, gets a line under the identifier asking for one (engine.studio.createItem.notDerived), wired by aria-describedby; Create stays off as before. (2) PackageFormDialog: the same case swaps the id-missing line to the reason (engine.packages.idRule.notDerived) and drops the filled-in mark over the empty box; an id the author cleared keeps the format line. (3) AddFieldPopover: shows the derived api name before Create; when the label derives none or a taken one it shows an API name box (toFieldNameLoose, same as the inspector) and Create waits for a free name; the host addField takes it as a third argument and both hosts pass takenNames. The silent field_N fallback stays only for a caller that hands no name. Part 2 (pinyin transliteration) is a product choice and went to the maintainer through the project's ruling flow with a recommendation; nothing of it is built. No spec or server change: the derivation is objectui client side, the spec states only the identifier alphabet. File surface: as claimed.",
"tests": "New: CreateItemDialog.notDerived-13389.test.tsx (4: Chinese name line + Create off + aria, zh-CN text, typed id clears and submits, CONTROL Latin/empty). PackageFormDialog.derivedFields-12512.test.tsx +2 (no-letters line and no mark, then typed id; CONTROL cleared id keeps the format line). DataPillar.addFieldPopover-12516.test.tsx: the pin that taken / no-letters labels get field_N is rewritten to the asked api names, +2 (Create off with reason until named, typed taken name refused; CONTROL Latin preview). Moved pins: StudioDesignSurface.autosaveInFlight-11204 and draftVersionConflict-11773 added New field twice and pinned the silent field_4; their second add now uses label Second field, and the shared helper takes an optional apiName. Ablation: each of notDerived, idNotDerived, asksName forced false on disk, 5 new or rewritten tests fail, files restored. pnpm exec vitest run packages/app-shell/src/views/studio-design/ packages/app-shell/src/views/metadata-admin/ :: 818 files, 8126 passed, 1 skipped, 2 files red (11204, 11773, the field_4 pins), then fixed and re-run :: 3 files, 17 passed.",
"gates": "Local: NODE_OPTIONS=--max-old-space-size=8192 pnpm exec turbo run type-check --filter=@object-ui/app-shell :: exit 0 (30 tasks); pnpm exec eslint on the changed files :: 0 errors (5 existing warnings); node scripts/check-changeset-presence.mjs :: pass; control-byte grep over the diff :: no hits. CI on 2c1247f: every check success (Build and E2E, Build Docs, Bundle Analysis, Changeset Bump Policy, Changeset Claim Re-read, Changeset Declaration, Changeset Fixed Group Check, Changeset Overwrite Report, Governed Surface Queue Guard, Line Citation Gate, Lint, Live E2E (informational), Repo Gates, Test, Test (dist pins), Test shards 1-16, Type Check, label); skipped: dependabot, Test (coverage), Test (coverage shard).",
"dogfood_battery": "n/a — objectui; no ! in the PR title and Clause-② no",
"mcp_calls": "github issue_read (get, get_comments) on objectui#13389 and objectstack-ai/objectui#13337, list_issues and list_pull_requests on objectui, pull_request_read (get on objectstack-ai/objectui#13398, get_check_runs on objectstack-ai/objectui#13414); claude-code-remote add_repo, register_repo_root, subscribe_pr_activity (session tools, not GitHub writes). No MCP write tool.",
"api_writes": "relay writes via scripts/pm on objectstack-ai/objectui: labels and assignee on objectstack-ai/objectui#13389 (label-write), claim comment 6371778384 (post-stamped), pr_create objectstack-ai/objectui#13414 with assignee os-sales and pr_request_reviewers os-sales (fleet-write dispatch), this report (post-stamped); plus git push of the branch",
"open_questions": ["Part 2: transliterate Chinese labels into a pinyin identifier (client pinyin-pro) or keep asking for a typed Latin identifier. Sent to the maintainer through the project's ruling flow, recommendation B (no transliteration). If B, objectstack-ai/objectui#13414 closes the card; if A, a second PR prefills the same boxes."],
"out_of_scope_findings": ["carrier: none · noted, not filed — the default package id prefix com.default. is the active organization's slug (default on a fresh deployment); the card asks for an org reverse-domain prompt; dedupe words: package id prefix com.default organization slug reverse domain"]
}
Ruled: B, by Sales (the maintainer), 2026-10-24, in the project's ruling thread, on the part-2 question of the claim 6371778384: transliterate a Chinese label into a pinyin identifier, or keep asking the author to type a Latin one.
13389 同意
— Sales, 2026-10-24T13:12Z, in reply to the decision card that recommended B (no transliteration). Relayed into this card thread by the project's coordinator; quoted verbatim, untranslated.
What B means here: no pinyin transliteration and no new client dependency. A label that derives no identifier is answered by the line beside the identifier and, on Add field, by the API name box. Part 1 already ships both, so nothing is left to build.
Completed by objectui#13414 (part 1), merged to main 2026-10-23T19:22Z through the merge queue (seat ACCEPT: PR comment 6372672720). That PR said Refs, so its merge did not close this card. Closing it now as completed and removing pm:dispatched.
Activity
objectstack-fleet commentedon Oct 23, 2026
Triage: lands in Studio's identifier derivation for New Package, New Object and Add Field (app-shell metadata-admin); rationale: a CJK display name derives nothing (blank required id, silently) or a positional
field_Nthat becomes a permanent API name at publish. At minimum say so beside the identifier and never mintfield_Nwithout inviting a rename; transliteration is the fuller fix.Path: studio · 不写代码建对象、字段 | studio-authoring.object-designer-roundtrip (P1, "identifiers derive…") | step ①
Grade:
priority:p2— P1 bound from the item; a tax (the author can type an id), not a wall, so one step under.Type: Bug
Dedupe: objectui search "Chinese display name identifier slug field_N pinyin" → no other hit.
Session:
session_01AkmasAfXt3cu83xGzkuKhe(objectstack triage, run on the maintainer's request in the project thread)Generated by Claude Code
objectstack-fleet commentedon Oct 23, 2026
Claim: card thread ·
domain:uiseat 1 (seat post #5560, project run by the Sales account) · 2026-10-23T18:19ZSession:
session_013zcUBV3ha3FeGmd9mV3Zza(a card thread of the project that runsdomain:uiseat 1, dispatched by its coordinator; 由Sales账户的项目负责)Account:
os-sales(the seat's linked user; the card's assignee from this stroke)Branch:
claude/issue-13389-cjk-identifierWorktree:
objectui-issue-13389Domain:
domain:uiSeat:
domain:ui#1File surface:
packages/app-shell/src/views/studio-design/CreateItemDialog.tsx(New Object and the other Studio create dialogs),packages/app-shell/src/views/metadata-admin/PackageFormDialog.tsx(New Package id and namespace lines),packages/app-shell/src/views/studio-design/AddFieldPopover.tsx,packages/app-shell/src/views/studio-design/ObjectFormDesigner.tsxandpackages/app-shell/src/views/studio-design/StudioDesignSurface.tsx(Add field's api name),packages/app-shell/src/views/metadata-admin/i18n.tsand the shipped locale packs (new strings), the tests of each,.changeset/(stop on breach; explain in the report)Container & model:
M,mode:thread,model: default judgment tier (dispatch-gates --tier --repo objectstack-ai/objectui names no path-derived mandate for this surface),effort: highClause-②: no
Metadata-protocol: none
Responsibility: objectui Studio's own create forms derive the identifier client side (
toFieldNameLoose,toIdSegment), drop every non-Latin letter, and say nothing; no platform path covers it (the spec only states the identifier alphabet); every zh-CN author who types a Chinese label reaches it todayThread-read: 6370409677
Serial constraints cleared: open objectui PRs read at claim time are #13395 (core ActionRunner), #13362, #13360, #13358 (workflows), #13289 (release), #13028 (timings data), #11845, #11844 (dependencies); none touches these paths. Open claims in this lane: #13384 (ActionRunner), #13350, objectstack-ai/objectstack#25936, #13348 (CI); none names these files.
Plan, stated so the review can hold it to it. Two parts:
field_N: when the label yields no api name, or yields one another field already holds, the popover shows an API name box the author fills before Create. A Latin label behaves as today.Refs, notFixes, until that ruling says whether part 2 is wanted.com.default.package id prefix the card mentions is the active organization's slug (defaulton a fresh deployment); it is noted in the report, not changed here.Generated by Claude Code
objectstack-fleet commentedon Oct 23, 2026
os-dev-report
{ "issue": 13389, "status": "done", "branch": "claude/issue-13389-cjk-identifier", "pr": "https://github.com/objectstack-ai/objectui/pull/13414", "session": "session_013zcUBV3ha3FeGmd9mV3Zza", "premise_still_valid": true, "summary": "Part 1 of the card, one PR, head 2c1247f, Refs objectstack-ai/objectui#13389 (part 1), not Fixes. (1) CreateItemDialog: a display name that derives no identifier, with none typed, gets a line under the identifier asking for one (engine.studio.createItem.notDerived), wired by aria-describedby; Create stays off as before. (2) PackageFormDialog: the same case swaps the id-missing line to the reason (engine.packages.idRule.notDerived) and drops the filled-in mark over the empty box; an id the author cleared keeps the format line. (3) AddFieldPopover: shows the derived api name before Create; when the label derives none or a taken one it shows an API name box (toFieldNameLoose, same as the inspector) and Create waits for a free name; the host addField takes it as a third argument and both hosts pass takenNames. The silent field_N fallback stays only for a caller that hands no name. Part 2 (pinyin transliteration) is a product choice and went to the maintainer through the project's ruling flow with a recommendation; nothing of it is built. No spec or server change: the derivation is objectui client side, the spec states only the identifier alphabet. File surface: as claimed.", "tests": "New: CreateItemDialog.notDerived-13389.test.tsx (4: Chinese name line + Create off + aria, zh-CN text, typed id clears and submits, CONTROL Latin/empty). PackageFormDialog.derivedFields-12512.test.tsx +2 (no-letters line and no mark, then typed id; CONTROL cleared id keeps the format line). DataPillar.addFieldPopover-12516.test.tsx: the pin that taken / no-letters labels get field_N is rewritten to the asked api names, +2 (Create off with reason until named, typed taken name refused; CONTROL Latin preview). Moved pins: StudioDesignSurface.autosaveInFlight-11204 and draftVersionConflict-11773 added New field twice and pinned the silent field_4; their second add now uses label Second field, and the shared helper takes an optional apiName. Ablation: each of notDerived, idNotDerived, asksName forced false on disk, 5 new or rewritten tests fail, files restored. pnpm exec vitest run packages/app-shell/src/views/studio-design/ packages/app-shell/src/views/metadata-admin/ :: 818 files, 8126 passed, 1 skipped, 2 files red (11204, 11773, the field_4 pins), then fixed and re-run :: 3 files, 17 passed.", "gates": "Local: NODE_OPTIONS=--max-old-space-size=8192 pnpm exec turbo run type-check --filter=@object-ui/app-shell :: exit 0 (30 tasks); pnpm exec eslint on the changed files :: 0 errors (5 existing warnings); node scripts/check-changeset-presence.mjs :: pass; control-byte grep over the diff :: no hits. CI on 2c1247f: every check success (Build and E2E, Build Docs, Bundle Analysis, Changeset Bump Policy, Changeset Claim Re-read, Changeset Declaration, Changeset Fixed Group Check, Changeset Overwrite Report, Governed Surface Queue Guard, Line Citation Gate, Lint, Live E2E (informational), Repo Gates, Test, Test (dist pins), Test shards 1-16, Type Check, label); skipped: dependabot, Test (coverage), Test (coverage shard).", "dogfood_battery": "n/a — objectui; no ! in the PR title and Clause-② no", "mcp_calls": "github issue_read (get, get_comments) on objectui#13389 and objectstack-ai/objectui#13337, list_issues and list_pull_requests on objectui, pull_request_read (get on objectstack-ai/objectui#13398, get_check_runs on objectstack-ai/objectui#13414); claude-code-remote add_repo, register_repo_root, subscribe_pr_activity (session tools, not GitHub writes). No MCP write tool.", "api_writes": "relay writes via scripts/pm on objectstack-ai/objectui: labels and assignee on objectstack-ai/objectui#13389 (label-write), claim comment 6371778384 (post-stamped), pr_create objectstack-ai/objectui#13414 with assignee os-sales and pr_request_reviewers os-sales (fleet-write dispatch), this report (post-stamped); plus git push of the branch", "open_questions": ["Part 2: transliterate Chinese labels into a pinyin identifier (client pinyin-pro) or keep asking for a typed Latin identifier. Sent to the maintainer through the project's ruling flow, recommendation B (no transliteration). If B, objectstack-ai/objectui#13414 closes the card; if A, a second PR prefills the same boxes."], "out_of_scope_findings": ["carrier: none · noted, not filed — the default package id prefix com.default. is the active organization's slug (default on a fresh deployment); the card asks for an org reverse-domain prompt; dedupe words: package id prefix com.default organization slug reverse domain"] }Generated by Claude Code
objectstack-fleet commentedon Oct 24, 2026
Ruled: B, by Sales (the maintainer), 2026-10-24, in the project's ruling thread, on the part-2 question of the claim 6371778384: transliterate a Chinese label into a pinyin identifier, or keep asking the author to type a Latin one.
— Sales, 2026-10-24T13:12Z, in reply to the decision card that recommended B (no transliteration). Relayed into this card thread by the project's coordinator; quoted verbatim, untranslated.
Seat: domain:ui#1
Session:
session_013zcUBV3ha3FeGmd9mV3Zza(由Sales账户的项目负责)What B means here: no pinyin transliteration and no new client dependency. A label that derives no identifier is answered by the line beside the identifier and, on Add field, by the API name box. Part 1 already ships both, so nothing is left to build.
Completed by objectui#13414 (part 1), merged to main 2026-10-23T19:22Z through the merge queue (seat ACCEPT: PR comment 6372672720). That PR said
Refs, so its merge did not close this card. Closing it now as completed and removingpm:dispatched.Generated by Claude Code