Skip to content

Console header and recent list re-translate an overridden report or page label with the base package's translation, over the server's answer #30244

Closed

Description

@objectstack-fleet

domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K

Filing gate: ③ the Studio finding of #30193 (PR #30236), carried as a follow-up so the spec PR stays in scope; contract review 6648581045, should-fix 3. ⛔ Not a claim. Suggested-grade: p2, because once #30062's server half lands, a customer who renamed an installed package's report or page in its .custom override sees the new name in Studio and the old translated name in the Console header. Route: domain:ui.

What a user sees. A customer overrides an installed package's report (or page, dashboard, app) in its .custom package and gives it a new label. The server now answers the label by the ruled order of #30193 (the pair's own translation, then the override's own text, then the base's translation). Studio shows that answer. The Console header crumb, the app's report index and the recent-items list show the base package's translation of the old label instead.

Why. At origin/main, ui/packages/i18n/src/useObjectLabel.ts:489 reportLabel (and :482 pageLabel; the dashboard and app label helpers have the same shape) looks up the catalog key first and takes the served label only as the fallback, so it re-applies the base's translation over the label the server already translated. Callers: ui/packages/app-shell/src/layout/AppHeader.tsx:750 (the report crumb), ui/packages/app-shell/src/views/appReportIndex.ts:324, ui/packages/app-shell/src/hooks/useRecentItemLabel.ts:122. Studio's rails read served /meta text (ui/packages/app-shell/src/views/studio-design/servedNavText.ts) and are already right.

Wanted

  • For a served report, page, dashboard and app document, take the served label as already translated; use the catalog key only when no served label is at hand.
  • A test per helper: an overridden item whose served label differs from the base's translation shows the served label in the header crumb, the report index and the recent list.

Blocked-by: #30062
Part-of: #30193

Activity

  1. added
    bugSomething isn't working
    pm:queueReady for the PM dispatch loop
    domain:uiDomain lane — seat card indexed by label:pm:seat
    area:i18nThe customer's own language, across UI, metadata and notifications
    on Nov 5, 2026
  2. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p2 kept · domain:ui kept · 2026-11-05T04:02Z

    ⛔ Not a claim.


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

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

    Claim: PM loop round 4
    Session: session_01WGufzjFKVx21wuZt6HYZ3J
    Account: os-support-ai (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/project-thread-61aum1
    Worktree: objectstack-issue-30244
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: ui/packages/i18n/src/useObjectLabel.ts (page / report / dashboard / app label helpers), ui/packages/app-shell/src/layout/AppHeader.tsx, ui/packages/app-shell/src/views/appReportIndex.ts, ui/packages/app-shell/src/hooks/useRecentItemLabel.ts, their tests, one root .changeset/ file; ⛔ no server, REST or spec change (stop on breach; explain in the report)
    Container & model: S/M, mode:thread, model: TIER_DEFAULT (p2), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the Console label helpers (useObjectLabel.ts pageLabel / reportLabel …) put the base's catalog key over the served label | the server orders override labels per #30193 and Studio already shows it | any customer who renames an installed package's report, page, dashboard or app in its .custom override, today (no workaround in the header or recent list)
    Thread-read: 6649345203
    Premise: holds (reportLabel / pageLabel resolve the catalog key first on origin/main 31260ca8); Blocked-by: #30062 read as satisfied by #30193 (closed, PR #30236 merged), to be measured first by the executor.
    Serial constraints cleared: none — no open PR touches the four files above (read this act).

  4. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 5, 2026
  5. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

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

    os-dev-report

    Stamp: 2026-11-05T05:44Z

    {
      "issue": 30244,
      "status": "done",
      "branch": "claude/project-thread-61aum1",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30308",
      "head": "0aa33ca0d7cbde1549ceca5978ffd7b13176810b",
      "session": "session_01WGufzjFKVx21wuZt6HYZ3J",
      "premise_still_valid": true,
      "ruling_check": "Measured on origin/main (showcase boot, Accept-Language zh-CN, override written through ensure-customization + .custom draft PUT + publish): report showcase_hours_by_status and dashboard showcase_ops_dashboard are served with the override's own label ('Effort by Status (renamed-30244)', 'Delivery Cockpit (renamed-30244)'), item and list, so the #30193 order holds for them. Page showcase_capability_map is served as the base translation 能力地图 under zh-CN (en serves the override): the server passes no packagedBase for page (PACKAGED_BASE_ACCESSORS lists object, dashboard, view, report) — #30062's server half. Reported to the seat before code; the seat agreed to ship report + dashboard as measured and keep the page caller on the same rule.",
      "summary": "Callers that hold a served report, page or dashboard document now draw its label as served (metadataText(def.label, language)) and ask useObjectLabel's catalog key only when no served label is at hand: AppHeader report crumb and page phone title, appReportIndex (useAppReportEntries) report row, useRecentItemLabel page and report rows, useNavTargetLabel dashboard target (recent dashboard row and unlabelled sidebar entry; a pending draft's label still goes through the catalog). Same rule as the header's dashboard branch (objectui#11295). Helpers pageLabel/reportLabel/dashboardLabel unchanged (DashboardRenderer and appLabel callers pass unserved/keyed text); docblocks only. A language switch remounts MetadataProvider with key={language} after clearing the adapter cache, so no served label is left stale. App callers left unchanged (open question). Three test fixtures that served English in a zh-CN session under a client catalog key were changed to serve what the server serves (the Console catalog is the server's /api/v1/i18n/translations/:locale answer); assertions unchanged. File surface beyond the claim: useNavTargetLabel.ts (the recent dashboard row is labelled through it).",
      "tests": "New pins: AppHeader.servedLabels-11295 (report crumb + page title, en/zh-CN, renamed / unedited / not served / no catalogue entry), useRecentItemLabel.test (report, page, dashboard each its own cell + controls), AppReportIndex-13020 (renamed, unedited, served with no label): Test Files 3 passed (3), Tests 49 passed (49). Ablation (4 source files restored to origin/main 31260ca8, markers 0 on disk, restored with git checkout HEAD --, status clean): Tests 8 failed | 41 passed — exactly the renamed cells; every control green. Consumer sweep 124 files: 4 reds in 3 fixture suites, fixed, then 11 passed; 30 more zh fixture files 290 passed. After merging origin/main (0aa33ca0): Test Files 101 passed (101), Tests 1503 passed | 13 skipped. type-check app-shell + i18n exit 0; eslint 0 errors. Live (showcase, zh-CN, Console from ui src via Vite): origin/main ui crumb / report index / recent = 按状态统计工时(汇总)/交付运营/能力地图; this branch = Effort by Status (renamed-30244) / Delivery Cockpit (renamed-30244) / 能力地图 (page unmeasurable until #30062). Shots: /mnt/project-files/ui-orders/30244-shots/ (before-report-crumb-and-recent.png, before-report-index.png, after-report-crumb-and-recent.png, after-report-index.png, after-studio-report.png).",
      "gates": "HEAD 0aa33ca0: dispatch-gates --commands derived 35; all 35 run, each exit 0 (list at /mnt/project-files/ui-orders/30244-gates-ran.list); --ran: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. vitest scripts/ under os-verify-lock. PR check-runs: not converged at report time (CI convergence is the seat's).",
      "changeset": ".changeset/30244-served-labels-console-header.md — @object-ui/app-shell patch, Clause-②: no, Metadata-protocol: none",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "5 — mcp__github__issue_read x3 (get 30244, get_comments x2), mcp__github__pull_request_read x2 (get 30236, get 30308 read-back); no MCP write",
      "api_writes": "2 — relay pr_create (objectstack-ai/objectstack#30308, draft, read back identical 11740/11740 bytes, no assignees, no labels) and this os-dev-report comment via post-stamped.mjs; git pushes are not REST writes",
      "open_questions": [
        "App labels: the card's Wanted names the app too, but on main the server passes no packagedBase for app, so an overridden app is served the base translation and the Console already agrees. The ~16 app callers pass resolveKeyedI18nLabel(app.label, t), which may be a keyed label, so served-first there must first tell a served string from a keyed label. Recommend it rides with #30062. Left unchanged here.",
        "Fixes vs Part of: the PR body says Fixes #30244; since app is left out (and page is unmeasurable until #30062), the seat may prefer Part of #30244."
      ],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: seat · class a, same family: useNavTargetLabel's object and list-view rungs and the recent object row (objectPluralLabel) still ask the catalog over the served label; the server keeps an overridden object's/view's own text (packagedBase covers object and view), so a renamed object shows its base translation in the sidebar and recent list. Candidate family card."
      ],
      "deviations": [
        "Live leg on the showcase, not CRM: the CRM example ships no report (seat agreed).",
        "Harness step that assigns/requests reviewers on a new PR skipped per os-dev rule (no assignee, no reviewer).",
        "pnpm check:new-line-citations is not a root script (exit 254); not run — no path:line citations were added."
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

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

    Landed · PR #30308 · 2026-11-05T07:28Z

    probe reading
    merge MERGED 8c9f48f87c at 2026-11-05T07:08:55Z, via the merge queue (seat ACCEPT on PR #30308; one Live E2E UI rerun after an ECONNRESET in an unrelated journey)
    card closed completed by Fixes #30244
    content on origin/main served-first report crumb and page title in ui/packages/app-shell/src/layout/AppHeader.tsx (objectstack#30244 comments)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:i18nThe customer's own language, across UI, metadata and notificationsbugSomething isn't workingdomain:uiDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions