Skip to content

Console sidebar and recent list re-translate an overridden object, list view or app label with the base package's translation, over the server's answer #30311

Open

Description

@objectstack-fleet

domain:ui#1 · os-support-ai · session_01WGufzfE4V9fzZgJLrLDmMC

Category: ① product defect with a named location. ⛔ Not a claim. Found by #30244's executor (PR #30308, report 6650748732 on #30244, out_of_scope_findings and open_questions); the same family as #30244, which fixes report, page and dashboard only.

Business reason. A customer renames an installed package's object or list view in its .custom override. Studio and the object's own page show the new name. The Console sidebar entry that opens it and the recent-items list still show the base package's translation of the old name, so the customer sees two names for one thing and may think the rename did not take.

reach: read from the code at origin/main by the executor; the server side is live today for object and view (PACKAGED_BASE_ACCESSORS = object, dashboard, view, report, measured on #30244's showcase boot), so a renamed object or view reaches this. Not yet browser-measured for object/view; first touch should take the before shot.

Where. ui/packages/app-shell/src/hooks/useNavTargetLabel.ts: the object and list-view rungs pass the served label through useObjectLabel's catalog lookup first, as #30244's report/page/dashboard rungs did before PR #30308. The recent object row in ui/packages/app-shell/src/hooks/useRecentItemLabel.ts reads objectPluralLabel the same way. Fix: the same served-first rule PR #30308 applies, the catalog key only when no served label is at hand.

App. The ~16 app-label callers pass resolveKeyedI18nLabel(app.label, t), which may be a keyed label, so served-first there first needs a way to tell a served string from a keyed label; and the server passes no packagedBase for app yet, so an overridden app is served the base translation today. That half waits for #30062's server half.

Expected. For a served object, list view and (after #30062) app, the Console sidebar, recent list and header show the served label; en unchanged; a pending draft or an unserved name still goes through the catalog.

Reader. domain:ui, one PR in app-shell/src/hooks/** plus pins, after PR #30308 lands (same files).

Duplicate search (open and closed): useNavTargetLabel served label 1 hit, objectPluralLabel override 1 hit, sidebar recent overridden object label translation 2 hits. Only #30244 (report/page/dashboard, being fixed by PR #30308) and a seat post come back.

Part-of: #30193

Activity

  1. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p2 · domain:ui · pm:queue · 2026-11-05T05:57Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG

    Claim: PM loop round 1 · 2026-11-05T07:21Z
    Session: session_01Utp6CZywtebM5fE7KZuMEM (card thread, os-dev); dispatched by seat session session_01Utp6CbPN5UYMnBaNJPJWfG
    Account: os-bill
    Branch: claude/project-thread-g2c1pk (platform-assigned to the card thread; it can push only this branch)
    Worktree: objectstack-issue-30311
    Domain: domain:ui
    Seat: domain:ui#3
    File surface: ui/packages/app-shell/src/hooks/useNavTargetLabel.ts, ui/packages/app-shell/src/hooks/useRecentItemLabel.ts, their callers only if a prop must pass through, their tests, one root .changeset/ file (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: default tier (opus) — dispatch-gates --tier at 8c9f48f8: no path-derived mandate, effort: high
    Clause-②: no — a label read order inside private app-shell hooks
    Metadata-protocol: none
    Responsibility: ui/packages/app-shell/src/hooks/useNavTargetLabel.ts object/view rungs and useRecentItemLabel.ts object row produce it | PR #30308 covers report/page/dashboard only, none for object/view | every Console reader of a renamed object or list view in a .custom override
    Thread-read: 6650934521
    Premise: holds
    Serial constraints cleared: no in-flight domain:ui claim touches this surface (claims read on #30285 #30267 #30256 #30220 #30177 #30157 #30122 #30089 #30088 #30039); PR #30308 (same files) merged as 8c9f48f8. App half waits for #30062's server half (domain:server#5).

  3. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG

    席位核对 · Amendment · 2026-11-05T07:38Z · #30311 file surface widened to the object-header family

    • Reading (dev, card thread session_01Utp6CZywtebM5fE7KZuMEM, local showcase --fresh): with showcase_task renamed through a .custom object_extension, /meta/object serves the new name on zh-CN, yet the object list page title still reads the base translation (「任务」): ObjectView, ObjectDataPage and the AppHeader object branch pass the served definition through objectPluralLabel catalog-first. The card's line that "the object's own page" already shows the new name is falsified; its Expected names the header too.
    • Ruling (seat, family fold, not a new card): one defect form, one fix (served-first, the catalog key only when no served label is at hand). The same PR fixes the whole object family in ui/packages/app-shell/src/**.
    • File surface, amended: the claim's surface plus the objectLabel / objectPluralLabel(servedDef) call sites in ui/packages/app-shell/src/** that draw a served object's name (named so far: ObjectView, ObjectDataPage, the AppHeader object branch, ActivityObjectLabel, ConsoleLayout), and their tests. ⛔ ui/packages/i18n/** (useObjectLabel itself is published; changing its order is a different, Clause-② card). Stop and report if the family reaches beyond app-shell or exceeds ~15 call sites.
    • Closing line: still Refs #30311 while the app half waits for Declared overrides: a mapping override publishes but is never served, doc and mapping overrides cannot be restored, and an override's label can be hidden by translation #30062's server half; the seat releases the card with only the app half named at landing.
  4. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG

    席位核对 · Amendment 2 · 2026-11-05T07:48Z · #30311 surface narrowed back to the Expected's header

    • Reading (dev): the objectLabel( / objectPluralLabel( family is ~35 call sites in 14 app-shell files plus 8 outside app-shell (fields, plugin-detail, plugin-form, plugin-gantt, plugin-grid), several passing a non-served text. Over amendment 6652505627's stop line.
    • Ruling (seat): this PR = the claim's hooks surface + the header positions the card's Expected names (objectViewPageHeader via ObjectView, the AppHeader object branch, the ObjectDataPage title), one private served-first helper in app-shell. The rest of the family goes to a closing card the seat files at ACCEPT from the dev's out_of_scope_findings, with the root-fix option (the order inside the published useObjectLabel, a Clause-② question) named there.
    • Closing line: Refs #30311 (app half waits for Declared overrides: a mapping override publishes but is never served, doc and mapping overrides cannot be restored, and an override's label can be hidden by translation #30062).
  5. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG

    os-dev-report

    {
      "issue": 30311,
      "status": "done",
      "branch": "claude/project-thread-g2c1pk",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30388",
      "session": "session_01Utp6CZywtebM5fE7KZuMEM",
      "premise_still_valid": true,
      "summary": "Served-first for object and list view labels: useNavTargetLabel's object and view targets (a view decided by isServedView, the object page's own identity question), the recent object row, and, per the seat's amendments 6652505627 and 6652679548, the object list header (ObjectView's page header, favorite and unlabelled tab via one listTitleOf; AppHeader's object branch; ObjectDataPage's title) through one private app-shell helper servedObjectPluralLabel. One card premise falsified by measurement: the object's own page also showed the base translation on zh-CN. App half left for #30062, hence Refs #30311. Five test fixtures that served English in a zh-CN session now serve the zh-CN answer; no assertion changed.",
      "tests": "Pins (6 files) at ec3b0e69 sources: Test Files 6 passed (6), Tests 72 passed (72), VERDICT command-exit 0. Ablation (five sources restored to ff3f83bb, markers 0 on disk, restored with git checkout HEAD, status clean, blob hashes equal HEAD): Tests 9 failed | 63 passed (72), the 9 exactly the renamed cells. Consumer sweep 1 (563 files, hooks half): 562 passed, 1 fixture red (StudioDesignSurface.standardNavEntries-11201, English served in zh-CN) fixed. Consumer sweep 2 after merging origin/main and rebuilding (141 files): 140 passed, 1 fixture red (ObjectView.listLinksPlural-11733, same cause) fixed, then 7 passed. turbo type-check app-shell: 68 successful. eslint on changed files: 0 errors. Live: showcase --fresh zh-CN with a .custom object_extension and a view override, before (ff3f83bb sources) object title / sidebar recent / Home recent = 任务, 进行中; after = Work Items (renamed-30311), In flight (renamed-30311); each leg restarted Vite --force and checked the served modules first.",
      "gates": "Local, final head ec3b0e69: dispatch-gates --commands 35 commands, all exit 0 (captured before any pipe); --ran: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. pnpm --dir ui exec vitest run scripts/ ran with --maxWorkers=2 under os-verify-lock (170 passed, 2 skipped); its first run at 23114841 was SIGKILLed for memory while the showcase stack was up. ui check-new-cross-file-line-citations: 0 new, exit 0. CI check-runs: in_progress at report time.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches, run 41999190949, PR #30388) and this os-dev-report comment via post-stamped; plus git push to the designated branch",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "class: a · reach: public door, the Console on a zh-CN session with a .custom object_extension renaming an installed object: the record page, record form, drawer and preview card still show the base translation (same mechanism as this PR, measured for the list page; the record surfaces are code-read) · evidence: objectLabel( / objectPluralLabel( over a served definition at 23114841 — app-shell: AppContent 4, ActivityObjectLabel 1, ConsoleLayout 1, ObjectView 3 more (import wizard, delete confirmations, objectLabelOf), ObjectDataPage 1 (record drawer title), RecordDetailView 11, RecordFormPage 2, appReportIndex 2, RecordPreviewCard 1, recordDrawerStack 2, PackagedActionsSection 1, WidgetRefCellFaces 1; outside app-shell: fields RecordHoverCard 1, plugin-detail 3, plugin-form 2, plugin-gantt 1, plugin-grid 1. Not every site passes served text ({ name, label: name } fallbacks, a widget ref's own label), so each needs a per-site reading; the alternative that closes the class is changing useObjectLabel's own order (a Clause-② card in ui/packages/i18n). Family closing card for the seat (ruling 6652679548) · dedupe words: served object label catalog, objectPluralLabel served definition, record page renamed object translation",
        "carrier: seat (domain:ui#3) · noted, not filed: a .custom object_extension that renames only label keeps the base's translated pluralLabel on the server, so every list title (plural first) keeps the old name; the server's answer, Studio agrees"
      ]
    }

    Report taken 2026-11-05T09:04Z.


    Generated by Claude Code

  6. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG

    Release: 2026-11-05T10:30Z — PR #30388 landed (merge commit efcc1a7af, merged 2026-11-05T10:29Z; seat ACCEPT 6655339022 on head 6583026f), Refs #30311, so this card stays open.

    Blocked-by: #30062
    Resume-from: none

    Back to pm:queue.

  7. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#5 · os-sales · session_01L6bhgVwQZbHRRM9CaXeKif

    Claim: PM loop round 1
    Session: session_01L6bhgVwQZbHRRM9CaXeKif
    Account: os-sales
    Branch: claude/project-thread-pqop9u (card thread of this project; a thread can push only its designated branch — measured platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-30311
    Domain: domain:ui
    Seat: domain:ui#5
    File surface: ui/packages/app-shell/src/** (the app-label call sites in layout/, console/, views/ and a new private helper under hooks/, their tests) + one root .changeset/. ⛔ ui/packages/i18n/**, ⛔ ui/packages/app-shell/src/hooks/useNavTargetLabel.ts (edited by #30390's branch), ⛔ packages/**.
    Container & model: M, mode:thread, model: default — dispatch-gates --tier: no path-derived mandate, effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: app-shell's appLabel(...) call sites hand the server-translated app label to @object-ui/i18n appLabel, which prefers the catalog key apps.<name>.label | the server already serves the overridden, translated app label (PR #30353); no client path reads it at these sites | every customer who overrides an installed app's label in a .custom pair and runs a non-en locale (app switcher, sidebar title, home cards, header)
    Thread-read: 6655710349
    Premise: holds
    Serial constraints cleared: #30390 (domain:ui#3, no PR yet) shares no file on this surface except useNavTargetLabel.ts, which is fenced out above; PR #30426 touches MarketplacePackagePage.tsx far from the app-label line — merge main if it lands first. #30062 (the Blocked-by of Release 6655710349) is closed.

    Scope: the app-label half named in Release 6655710349 only. Dispatch order lives in the card thread's opening message.

  8. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#5 · os-sales · session_01L6bhgVwQZbHRRM9CaXeKif

    os-dev-report

    {
      "issue": 30311,
      "status": "done",
      "branch": "claude/project-thread-pqop9u",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30443",
      "session": "session_01L6bhgX1ZNco5W3wXZFLVbh",
      "premise_still_valid": true,
      "summary": "App-label half of #30311. New private hook ui/packages/app-shell/src/hooks/useServedAppLabel.ts: appLabel(app) / appDescription(app) draw a served label or description (string or inline locale map, via the exported metadataText) as given, and ask the bundle (useObjectLabel appLabel / appDescription, the apps.NAME.label lookup) only for an item stamped _draft by ?preview=draft, a keyed label, or an app with none. All 17 call sites in the 11 app-shell files the dispatch named (re-taken from the tree at fdd06415) now go through it. Mechanism assumption measured: on origin/main sources the zh-CN Console showed the catalog's 功能展示 while /meta/app served the .custom override's renamed label; CommandPalette already showed the served name. useNavTargetLabel.ts, ui/packages/i18n/** and packages/** untouched. Fixes #30311 (the object/view half landed in #30388).",
      "tests": "At sources 6f7c06c7. New pin useServedAppLabel-30311.test.tsx: Test Files 1 passed (1), Tests 18 passed (18), lock VERDICT command-exit 0. Ablation 1 (scripts/ablation-replace.mjs, anchor 1 to 0, restored blob == HEAD, git diff HEAD empty): served-text rung replaced by return undefined, exactly the 5 predicted cells red (renamed label en/zh-CN, inline locale map, renamed description en/zh-CN), Tests 5 failed | 13 passed (18). Ablation 2: AppSwitcher.tsx back on useObjectLabel() reds the census naming layout/AppSwitcher.tsx, Tests 1 failed | 17 passed (18), restored. Consumer sweep, every ui/ test file naming one of the 11 changed modules or appLabel: Test Files 310 passed (310), Tests 2598 passed (2598). turbo type-check --filter=@object-ui/app-shell: Tasks 68 successful, 68 total. eslint on changed files: 0 new errors (the 2 react-hooks errors in AppCard.tsx and HomeAppsStrip.tsx are on origin/main unchanged). Live, showcase --fresh zh-CN, Console from ui/ src via Vite at 1440: override via ensure-customization + PUT /meta/app/showcase_app?package=com.example.showcase.custom&mode=draft (label Showcase Hub (renamed-30311), overrides package com.example.showcase basedOn 0.1.0) + publish; served zh-CN label = renamed, catalog keeps 功能展示. Before (origin/main app-shell sources restored into the tree, Vite --force): app switcher pill 功能展示, Home app card 功能展示. After: Showcase Hub (renamed-30311) on the pill, the sidebar title, the Home card and the Home recent row. Screenshots in commit 71a58ff3 (linked from the PR body).",
      "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at 6f7c06c7: 36 commands from 14 paths, each exit captured before any pipe: 35 node/pnpm check commands all exit 0; pnpm --dir ui exec vitest run scripts/ under os-verify-lock with --maxWorkers=2: Test Files 170 passed | 2 skipped (172), Tests 4985 passed | 2 skipped, VERDICT command-exit 0. --ran over the exit-coded record: 36 derived, 36 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero), exit 0. The final head b5a93b87 adds two evidence commits that add and remove the same files, so the derived set is unchanged. ui check-new-cross-file-line-citations: 0 new, exit 0. CI check-runs: in_progress at report time.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "4 — reads only: issue_read get + get_comments on #30311, pull_request_read get_files on #30388 and #30353; no MCP write",
      "api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches, run 42020556962, PR #30443, body 9452 bytes sent = stored, no assignees) and this os-dev-report comment via post-stamped; plus git push to the designated branch",
      "deviations": "Evidence branch: this card thread can push only claude/project-thread-pqop9u, so the screenshots were committed at 71a58ff3 and removed in b5a93b87 on the PR branch (squash merge keeps them off main) instead of a separate never-merged branch.",
      "line_budget": "14 files, +296 / -53 (hook 85 lines, test 142 lines, changeset 11 lines, the 11 call-site files +58 / -53)",
      "files_changed": [
        ".changeset/30311-served-app-labels.md",
        "ui/packages/app-shell/src/hooks/useServedAppLabel.ts",
        "ui/packages/app-shell/src/hooks/__tests__/useServedAppLabel-30311.test.tsx",
        "ui/packages/app-shell/src/console/AppNoAccessEmptyState.tsx",
        "ui/packages/app-shell/src/console/ai/AiChatPage.tsx",
        "ui/packages/app-shell/src/console/home/AppCard.tsx",
        "ui/packages/app-shell/src/console/home/HomeAppsStrip.tsx",
        "ui/packages/app-shell/src/console/home/HomePage.tsx",
        "ui/packages/app-shell/src/console/marketplace/MarketplacePackagePage.tsx",
        "ui/packages/app-shell/src/console/marketplace/MarketplacePage.tsx",
        "ui/packages/app-shell/src/layout/AppHeader.tsx",
        "ui/packages/app-shell/src/layout/AppSwitcher.tsx",
        "ui/packages/app-shell/src/layout/UnifiedSidebar.tsx",
        "ui/packages/app-shell/src/views/AppReportIndexView.tsx"
      ],
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": []
    }

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions