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 }}
Repository navigation
showcase (zh-CN): the task detail page's "Awaiting review" callout stays English — its record:alert has no component id, so no translation can address it #28982
On a zh-CN session, the showcase task detail page (showcase_task_detail) renders every platform and object label in Chinese, but its review callout reads in English:
title "Awaiting review"
body "This task is in review — confirm the work before marking it done."
The callout shows for any task with status = in_review. The seed ships one ("Design system"), and the assignment notification of the checklist item lands on it.
Measured at framework 7fa9873f (main, 2026-11-02) on a stock showcase boot from a scratch copy, Console built from the same tree.
Reproduction
Boot the showcase; sign in as admin with a zh-CN browser locale (GET /api/v1/auth/me/localization answers locale: zh-CN).
Open /_console/apps/com.example.showcase/showcase_task/record/ID for the seeded task "Design system" (status 评审中).
Expected: the callout in Chinese, like the rest of the page.
Actual: "Awaiting review / This task is in review — confirm the work before marking it done." in English, above zh highlights (项目/负责人/优先级/截止日期/进度) and zh sections (概览/排期).
examples/app-showcase/src/ui/pages/task-detail.page.ts (around L94–104) declares the record:alert with visibleWhen and properties.title/body but no id. Page copy is translated through pages.NAME.components.COMPONENT_ID.KEY (packages/spec/src/system/translation.zod.ts, the pages block), so an id-less component cannot be addressed, and the zh-CN bundle carries no entry for it.
Read fresh. The showcase task-detail "Awaiting review" record:alert has no component id, so no zh-CN translation can address it, and i18n.notification-localized-and-clears A1 (no mixed-language page) fails on the release checklist. The fix is in examples/app-showcase (a component id in task-detail.page.ts, plus the zh-CN rows), the QA showcase the checklist runs on: domain:devx, p2.
Claim: PM loop round 2
Session: session_017ihL2gLghEqeDKTbDTC7Zd
Account: marchtian
Branch: claude/issue-28982-showcase-review-alert-zh
Worktree: objectstack-issue-28982
Domain: domain:devx
Seat: domain:devx#2
File surface: examples/app-showcase/src/ui/pages/task-detail.page.ts (a component id on the review record:alert) and examples/app-showcase/src/system/translations/index.ts (the zh-CN pages.showcase_task_detail.components.ID rows), plus any showcase test or checklist pin that counts translated page components
Container & model: S/M fix, mode:subagent, model: default tier, effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: the review callout has no component id, so the translation bundle cannot address it
Thread-read: 6570277361
Premise: holds
Serial constraints cleared: none (no open PR touches these files at claim time)
Triaged p2 by triage#1 (6570277361). Every statement the fix writes is read off the current head before it is written; the reproduction in the card is re-checked first.
{
"issue": 28982,
"status": "done",
"branch": "claude/issue-28982-showcase-review-alert-zh",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29104",
"head": "6c6289c0c9",
"session": "session_017ihL2gLghEqeDKTbDTC7Zd",
"premise_still_valid": true,
"premise_note": "The id-less record:alert premise holds at ab085a0482. The card's prescription 'pages.showcase_task_detail.components.ID.title/body' is half-measurable: only title has a key on the page-component face, and the bundle schema refuses body. The body therefore ships as an inline locale map.",
"summary": "The Task Detail review banner (record:alert) now carries id review_alert, and the zh-CN bundle translates its title (待评审) through pages.showcase_task_detail.components.review_alert.title. body is not on the page-component copy face (PAGE_COMPONENT_COPY_KEYS), and the strict bundle schema refuses it there, so it is now an inline locale map holding en and zh-CN. RecordAlertProps.body is I18nLabelSchema, and the renderer reads it through pickLocalized. A fixed dismissKey stops the bundle-translated title from moving the dismissal key between locales. A new test pins all of this against the app's own bundle.",
"tests": "pnpm --filter @objectstack/example-showcase exec vitest run --maxWorkers=2 test/task-detail-review-alert-zh-cn.test.ts: 3/3 passed. Reverse check, once: both source files restored to base ab085a0482 gave 1 failed and 2 passed ('expected undefined to be review_alert'); restored from HEAD, git diff HEAD empty. Full package at head 6c6289c0c9, run under the lock: typecheck plus vitest, VERDICT command-exit 0, Test Files 43/43, Tests 514/514. pnpm --filter @objectstack/example-showcase validate: exit 0, no finding on showcase_task_detail. No ablation: no tested runtime behaviour changed (example metadata only).",
"gates": "dispatch-gates --commands at 6c6289c0c9 derived 40 commands. 39 exited 0, including check:i18n-coverage ('OK (14 config(s), 426 baselined untranslated string(s), none new)'), check:page-declaration-shape, check:nul-bytes, check:examples-live-imports, check:closing-keyword-parity and check:cross-package-test-inputs. check:dual-build-cjs-loads exited 3 (PREREQUISITE NOT MET: no dist for studio, client-react, embedder-openai, knowledge-memory, knowledge-ragflow, service-cluster-redis or service-knowledge), so it is NOT MEASURED locally and left to CI. --ran reconciliation (exit codes recorded): '40 derived famil(ies) accounted for — 39 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)'. PR check-runs: in_progress when this report was written, not awaited.",
"line_budget": "no budget in the order; measured +88 / -1 across 3 files (dispatch-gates: 89 changed lines, under the 3000 human-merge threshold). Most of the added lines are the comment block and the new test file.",
"files_changed": [
"examples/app-showcase/src/ui/pages/task-detail.page.ts",
"examples/app-showcase/src/system/translations/index.ts",
"examples/app-showcase/test/task-detail-review-alert-zh-cn.test.ts"
],
"claims": [
{ "claim": "The zh-CN title reaches the banner through the component-id route", "backed_by": "packages/spec/src/system/i18n-resolver.ts translatePage (lookupPageComponentCopy on the addressed id); examples/app-showcase/src/system/translations/index.ts:1251; task-detail.page.ts:110; pinned by the new test's first case" },
{ "claim": "body has no key on the page-component bundle face and the bundle refuses it", "backed_by": "i18n-resolver.ts:2803 PAGE_COMPONENT_COPY_KEYS = title/description/label/placeholder/emptyText; translation.zod.ts:1429 components strictObject. Measured on the built spec: {title} parses; {title, body} gives unrecognized_keys at zh-CN.pages.p.components.a ('Unrecognized key(s) on this page component translation: `body`')" },
{ "claim": "The inline locale map on body renders in the reader's locale", "backed_by": "packages/spec/src/ui/component.zod.ts:2291 RecordAlertProps.body is I18nLabelSchema; ui/packages/plugin-detail/src/renderers/record-alert.tsx:204 pickLocalized(props.body, language). The served document keeps the map intact: the new test's first case" },
{ "claim": "The inline map is the recorded route for page prose with no bundle key", "backed_by": "packages/spec/src/system/translation.zod.ts, the pages.components doc block: the 'content is not here' exclusion says the inline locale map is the ruled route for page prose" },
{ "claim": "Without a fixed dismissKey, a translated title would move the dismissal key", "backed_by": "record-alert.tsx:248 key = props.dismissKey || pickLocalized(props.title, 'en') || severity; task-detail.page.ts:122" },
{ "claim": "The showcase ships only en and zh-CN, so no other locale needs the key; en keeps the authored English", "backed_by": "examples/app-showcase/objectstack.config.ts:192 supportedLocales ['en', 'zh-CN']; the en block of translations/index.ts has no pages entry; the new test's second case" },
{ "claim": "The i18n coverage ratchet is unchanged", "backed_by": "pnpm check:i18n-coverage exit 0, 'none new'" }
],
"deviations": [
"Scope said zh-CN title/body under the bundle key. body cannot go there (see claims), so it ships as an inline locale map on the page. The order's ruling binds the id route, and this applies it to the one key that route can carry.",
"Added dismissKey: 'showcase_task_review' on the same node. It is a direct consequence of translating the title (see claims). Someone who dismissed the banner under the old English-title key sees it once more.",
"packages/spec moved on the main side of the single merge (record-page.zod.ts and generated api snapshots); this diff touches no spec file. Spec check:generated was not run locally; CI's TypeScript Type Check owns it.",
"test:repo (vitest repo project) was not run locally; Test Core in CI runs it.",
"check:dual-build-cjs-loads NOT MEASURED locally (exit 3, prerequisite), left to CI.",
"PR body ends with the order's line ('Generated with Claude Code' and the claude.com link) instead of os-dev's session-URL footer form. I followed the order."
],
"dogfood_battery": "n/a — no ! in the PR title and Clause-②: no without a (narrowing) arm",
"changeset": "none. @objectstack/example-showcase is private: true, so the PR carries skip-changeset (sent with pr_create; read back on the PR).",
"mcp_calls": "0",
"api_writes": "2 — (1) relay dispatch POST /repos/objectstack-ai/objectstack/dispatches, carrying pr_create plus its labels leg (skip-changeset), run 41406317116 success, read-back identical, 6576 bytes; (2) this comment through post-stamped.mjs. git push of the branch is not a REST write.",
"open_questions": [],
"out_of_scope_findings": [
"class: observation (read-only inference, no browser run) · reach: none measured · evidence: a survey of the 29 exported showcase pages for id-less components carrying copy on the page-component face. showcase_my_work: object-metric label/description (Open Tasks, In Review, At-Risk Projects) and page:card titles Shortcuts and Leadership View. showcase_component_gallery: 4 object-metric blocks and an element:button 'Create Task'. showcase_project_detail: record:line_items and record:related_list title 'Tasks'. Without an id none of these can take a zh-CN bundle key · dedupe words: showcase zh-CN id-less page component; my work KPI English; object-metric label translation · carrier: none · noted, not filed",
"class: observation · reach: none measured · evidence: several element:text content strings on showcase_my_work, showcase_component_gallery, showcase_contact_form and showcase_page_variables are plain English strings. Their route is an inline locale map, not the bundle · dedupe words: showcase element:text content inline locale map · carrier: none · noted, not filed",
"class: boundary, not (c) · reach: named producer (this card's prescription wrote body under the bundle key) · evidence: a body key under pages.NAME.components.ID is refused loudly at parse with a located unrecognized_keys error. It is not silently dropped, so it is outside class (c) · carrier: none · noted, not filed"
]
}
Landed · 2026-11-02T09:07Z · PR #29104 merged as 692e0dc8b9 (reviewed head 6c6289c0c9, seat record ACCEPT on the PR). The showcase task detail review banner now renders in Chinese under zh-CN. Its title comes from the bundle at pages.showcase_task_detail.components.review_alert.title, its body from an inline locale map (the page-component copy face has no body key), and a fixed dismissKey keeps a dismissal valid in both languages. The dev also listed other id-less showcase copy, read from source only. It is noted on the PR record and will be filed once a zh-CN run confirms it. pm:dispatched is removed in this stroke.
Activity
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: p2 ·
domain:devx·area:i18n·pm:queue· 2026-11-02T06:01Z⛔ Not a claim.
record:alerthas no component id, so no zh-CN translation can address it, andi18n.notification-localized-and-clearsA1 (no mixed-language page) fails on the release checklist. The fix is inexamples/app-showcase(a componentidintask-detail.page.ts, plus the zh-CN rows), the QA showcase the checklist runs on:domain:devx, p2.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:devx#2 · marchtian · session_017ihL2gLghEqeDKTbDTC7Zd
Claim: PM loop round 2
Session:
session_017ihL2gLghEqeDKTbDTC7ZdAccount:
marchtianBranch:
claude/issue-28982-showcase-review-alert-zhWorktree:
objectstack-issue-28982Domain:
domain:devxSeat:
domain:devx#2File surface:
examples/app-showcase/src/ui/pages/task-detail.page.ts(a componentidon the reviewrecord:alert) andexamples/app-showcase/src/system/translations/index.ts(the zh-CNpages.showcase_task_detail.components.IDrows), plus any showcase test or checklist pin that counts translated page componentsContainer & model:
S/M fix,mode:subagent,model: default tier,effort: highClause-②: no
Metadata-protocol: none
Responsibility: the review callout has no component id, so the translation bundle cannot address it
Thread-read: 6570277361
Premise: holds
Serial constraints cleared: none (no open PR touches these files at claim time)
Triaged p2 by triage#1 (6570277361). Every statement the fix writes is read off the current head before it is written; the reproduction in the card is re-checked first.
objectstack-fleet commentedon Nov 2, 2026
domain:devx#2 · marchtian · session_017ihL2gLghEqeDKTbDTC7Zd
os-dev-report
{ "issue": 28982, "status": "done", "branch": "claude/issue-28982-showcase-review-alert-zh", "pr": "https://github.com/objectstack-ai/objectstack/pull/29104", "head": "6c6289c0c9", "session": "session_017ihL2gLghEqeDKTbDTC7Zd", "premise_still_valid": true, "premise_note": "The id-less record:alert premise holds at ab085a0482. The card's prescription 'pages.showcase_task_detail.components.ID.title/body' is half-measurable: only title has a key on the page-component face, and the bundle schema refuses body. The body therefore ships as an inline locale map.", "summary": "The Task Detail review banner (record:alert) now carries id review_alert, and the zh-CN bundle translates its title (待评审) through pages.showcase_task_detail.components.review_alert.title. body is not on the page-component copy face (PAGE_COMPONENT_COPY_KEYS), and the strict bundle schema refuses it there, so it is now an inline locale map holding en and zh-CN. RecordAlertProps.body is I18nLabelSchema, and the renderer reads it through pickLocalized. A fixed dismissKey stops the bundle-translated title from moving the dismissal key between locales. A new test pins all of this against the app's own bundle.", "tests": "pnpm --filter @objectstack/example-showcase exec vitest run --maxWorkers=2 test/task-detail-review-alert-zh-cn.test.ts: 3/3 passed. Reverse check, once: both source files restored to base ab085a0482 gave 1 failed and 2 passed ('expected undefined to be review_alert'); restored from HEAD, git diff HEAD empty. Full package at head 6c6289c0c9, run under the lock: typecheck plus vitest, VERDICT command-exit 0, Test Files 43/43, Tests 514/514. pnpm --filter @objectstack/example-showcase validate: exit 0, no finding on showcase_task_detail. No ablation: no tested runtime behaviour changed (example metadata only).", "gates": "dispatch-gates --commands at 6c6289c0c9 derived 40 commands. 39 exited 0, including check:i18n-coverage ('OK (14 config(s), 426 baselined untranslated string(s), none new)'), check:page-declaration-shape, check:nul-bytes, check:examples-live-imports, check:closing-keyword-parity and check:cross-package-test-inputs. check:dual-build-cjs-loads exited 3 (PREREQUISITE NOT MET: no dist for studio, client-react, embedder-openai, knowledge-memory, knowledge-ragflow, service-cluster-redis or service-knowledge), so it is NOT MEASURED locally and left to CI. --ran reconciliation (exit codes recorded): '40 derived famil(ies) accounted for — 39 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)'. PR check-runs: in_progress when this report was written, not awaited.", "line_budget": "no budget in the order; measured +88 / -1 across 3 files (dispatch-gates: 89 changed lines, under the 3000 human-merge threshold). Most of the added lines are the comment block and the new test file.", "files_changed": [ "examples/app-showcase/src/ui/pages/task-detail.page.ts", "examples/app-showcase/src/system/translations/index.ts", "examples/app-showcase/test/task-detail-review-alert-zh-cn.test.ts" ], "claims": [ { "claim": "The zh-CN title reaches the banner through the component-id route", "backed_by": "packages/spec/src/system/i18n-resolver.ts translatePage (lookupPageComponentCopy on the addressed id); examples/app-showcase/src/system/translations/index.ts:1251; task-detail.page.ts:110; pinned by the new test's first case" }, { "claim": "body has no key on the page-component bundle face and the bundle refuses it", "backed_by": "i18n-resolver.ts:2803 PAGE_COMPONENT_COPY_KEYS = title/description/label/placeholder/emptyText; translation.zod.ts:1429 components strictObject. Measured on the built spec: {title} parses; {title, body} gives unrecognized_keys at zh-CN.pages.p.components.a ('Unrecognized key(s) on this page component translation: `body`')" }, { "claim": "The inline locale map on body renders in the reader's locale", "backed_by": "packages/spec/src/ui/component.zod.ts:2291 RecordAlertProps.body is I18nLabelSchema; ui/packages/plugin-detail/src/renderers/record-alert.tsx:204 pickLocalized(props.body, language). The served document keeps the map intact: the new test's first case" }, { "claim": "The inline map is the recorded route for page prose with no bundle key", "backed_by": "packages/spec/src/system/translation.zod.ts, the pages.components doc block: the 'content is not here' exclusion says the inline locale map is the ruled route for page prose" }, { "claim": "Without a fixed dismissKey, a translated title would move the dismissal key", "backed_by": "record-alert.tsx:248 key = props.dismissKey || pickLocalized(props.title, 'en') || severity; task-detail.page.ts:122" }, { "claim": "The showcase ships only en and zh-CN, so no other locale needs the key; en keeps the authored English", "backed_by": "examples/app-showcase/objectstack.config.ts:192 supportedLocales ['en', 'zh-CN']; the en block of translations/index.ts has no pages entry; the new test's second case" }, { "claim": "The i18n coverage ratchet is unchanged", "backed_by": "pnpm check:i18n-coverage exit 0, 'none new'" } ], "deviations": [ "Scope said zh-CN title/body under the bundle key. body cannot go there (see claims), so it ships as an inline locale map on the page. The order's ruling binds the id route, and this applies it to the one key that route can carry.", "Added dismissKey: 'showcase_task_review' on the same node. It is a direct consequence of translating the title (see claims). Someone who dismissed the banner under the old English-title key sees it once more.", "packages/spec moved on the main side of the single merge (record-page.zod.ts and generated api snapshots); this diff touches no spec file. Spec check:generated was not run locally; CI's TypeScript Type Check owns it.", "test:repo (vitest repo project) was not run locally; Test Core in CI runs it.", "check:dual-build-cjs-loads NOT MEASURED locally (exit 3, prerequisite), left to CI.", "PR body ends with the order's line ('Generated with Claude Code' and the claude.com link) instead of os-dev's session-URL footer form. I followed the order." ], "dogfood_battery": "n/a — no ! in the PR title and Clause-②: no without a (narrowing) arm", "changeset": "none. @objectstack/example-showcase is private: true, so the PR carries skip-changeset (sent with pr_create; read back on the PR).", "mcp_calls": "0", "api_writes": "2 — (1) relay dispatch POST /repos/objectstack-ai/objectstack/dispatches, carrying pr_create plus its labels leg (skip-changeset), run 41406317116 success, read-back identical, 6576 bytes; (2) this comment through post-stamped.mjs. git push of the branch is not a REST write.", "open_questions": [], "out_of_scope_findings": [ "class: observation (read-only inference, no browser run) · reach: none measured · evidence: a survey of the 29 exported showcase pages for id-less components carrying copy on the page-component face. showcase_my_work: object-metric label/description (Open Tasks, In Review, At-Risk Projects) and page:card titles Shortcuts and Leadership View. showcase_component_gallery: 4 object-metric blocks and an element:button 'Create Task'. showcase_project_detail: record:line_items and record:related_list title 'Tasks'. Without an id none of these can take a zh-CN bundle key · dedupe words: showcase zh-CN id-less page component; my work KPI English; object-metric label translation · carrier: none · noted, not filed", "class: observation · reach: none measured · evidence: several element:text content strings on showcase_my_work, showcase_component_gallery, showcase_contact_form and showcase_page_variables are plain English strings. Their route is an inline locale map, not the bundle · dedupe words: showcase element:text content inline locale map · carrier: none · noted, not filed", "class: boundary, not (c) · reach: named producer (this card's prescription wrote body under the bundle key) · evidence: a body key under pages.NAME.components.ID is refused loudly at parse with a located unrecognized_keys error. It is not silently dropped, so it is outside class (c) · carrier: none · noted, not filed" ] }objectstack-fleet commentedon Nov 2, 2026
domain:devx#2 · marchtian · session_017ihL2gLghEqeDKTbDTC7Zd
Landed · 2026-11-02T09:07Z · PR #29104 merged as
692e0dc8b9(reviewed head6c6289c0c9, seat record ACCEPT on the PR). The showcase task detail review banner now renders in Chinese under zh-CN. Itstitlecomes from the bundle atpages.showcase_task_detail.components.review_alert.title, itsbodyfrom an inline locale map (the page-component copy face has nobodykey), and a fixeddismissKeykeeps a dismissal valid in both languages. The dev also listed other id-less showcase copy, read from source only. It is noted on the PR record and will be filed once a zh-CN run confirms it.pm:dispatchedis removed in this stroke.