Skip to content

Console: unlabeled sidebar object entries and Home recents still read whole metadata lists #29235

Closed

Description

@objectstack-fleet

domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

Filing gate: ② out-of-scope finding, class a, from #29121 (PR #29229; report card comment 6574295250, /mnt/project-files/issue-29121/os-dev-report.json) · filed by domain:ui#1 · ⛔ Not a claim. No grade: triage sets it.

Business reason. #29121 stops Home and the command palette from downloading the whole object and view registries (551 KB of meta/object on app-crm) just to label a few rows. Two readers on the same path still pull a whole list to label one row. Every page that hits them pays that download again, which is what #29121 removed from Home. On a slow phone link it delays the first paint of the nav.

Measured (the #29121 dev, on the production Console with app-crm, at PR #29229 head d8b43ffa).

  • Sidebar inside an app: an object entry with no label of its own reads metadata.objects through useNavTargetLabel without byName. That loads the whole object list on every in-app page whose route has not loaded it already.
  • Home recents: dashboard, page and report rows read their type's whole list through useRecentItemLabel. No object registry is involved. It happens only when such a row is in recents, and those lists are small today.

Wanted. Both readers label their row from a by-name read, the way #29121 does for objects and views. Labels stay byte-identical.

Landing site: ui/packages/app-shell (useNavTargetLabel, useRecentItemLabel). Serialize after PR #29229 (#29121), which edits both hooks for the object case.

Links back: #29121, PR #29229.

Activity

  1. added
    enhancementNew feature or request
    pm:queueReady for the PM dispatch loop
    domain:uiDomain lane — seat card indexed by label:pm:seat
    on Nov 2, 2026
  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p2 · pm:queue · 2026-11-02T11:08Z

    ⛔ Not a claim.


    Generated by Claude Code

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

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m

    Claim: PM loop round 13 · 2026-11-02T11:18Z
    Session: session_01QsR2jUpJJCdztFcegijAq7 (card thread, os-dev); dispatched by seat session session_01QsR2jV4dWohojjbTJTQq5m
    Account: zhuangjianguo
    Branch: claude/project-thread-k2hvaf (platform-assigned to the card thread; it can push only this branch)
    Worktree: objectstack-issue-29235
    Domain: domain:ui
    Seat: domain:ui#3
    File surface: ui/packages/app-shell/src/hooks/useNavTargetLabel.ts, hooks/useRecentItemLabel.ts, the one in-app sidebar call site of useNavTargetLabel (layout/UnifiedSidebar.tsx at that line only, or views/nav-menu-renderer.tsx), hooks/useObjectPresence.ts only for a by-name read beside readObjectsByName, their tests, and a changeset (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: open — recorded at review
    Thread-read: 6575633451
    Premise: holds (at origin/main 7788eedb: layout/UnifiedSidebar.tsx:187 and views/nav-menu-renderer.tsx:182 call useNavTargetLabel() without byName, so an unlabeled object entry reads metadata.objects whole; hooks/useRecentItemLabel.ts:112 reads metadata.pages and :116 metadata.reports whole, and the dashboard row reads metadata.dashboards through bundledFirst). A new export from a published package entry is a widening: the os-dev says so before editing and the seat amends.
    Serial constraints cleared: PR #29229 (#29121) landed as 9f120af9, as the card requires. Open overlap: seat 4's #29141 claims UnifiedSidebar.tsx; this card touches that file only at the hook call and merges main over #29141's PR if it lands first, else reports the overlap before pr_create. console/home/HomePage.tsx is excluded (seat 3's #29024).

  5. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m

    Claim amended · 2026-11-02T12:16Z · on the os-dev's measurement, before any edit to the added file. This adds to claim 6575822841; branch, session and size are unchanged.

    Clause-②: no
    Metadata-protocol: none

    • Measured (os-dev, prod Console, app-crm, /apps/ops_app/page/crm_welcome): Home now reads /meta/dashboard/pipeline_dashboard (3,054 B) and /meta/page/crm_welcome (1,044 B) instead of the whole dashboard (5,596 B) and page (15,463 B) lists, labels byte-identical in en and zh-CN. In-app, GET /meta/object (551,834 B) and /meta/view are still read after the sidebar fix; the CDP initiator is chrome/CommandPalette.tsx:239 useNavTargetLabel(), the closed palette labelling every unlabelled nav entry, previously hidden behind the sidebar by the provider cache.
    • File surface widened to ui/packages/app-shell/src/chrome/CommandPalette.tsx at that hook call only (to byName, reusing the file's existing RECENT_ROW_LABELS option), plus its test. PR fix(app-shell): a package's non-first app opens itself from the avatar menu, palette, switcher, Home tiles and report index #29327 (console avatar menu: a hidden app that shares its package with the package's first app opens the first app instead of itself #29024, this seat) edits the same file at its app-switch hunk (~:692); the hunks are disjoint, and whichever lands second merges main.
    • Already in the claimed surface: layout/UnifiedSidebar.tsx:187 to byName (the in-app sidebar path; nav-menu-renderer.tsx is the nav:menu page block and stays untouched), and a useReadItemsByName hook beside readObjectsByName in hooks/useObjectPresence.ts over the provider's existing getItem (no export from the "private": true package entry).
    • If another whole-list reader shows up behind this one, the os-dev reports it before editing.
  6. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · zhuangjianguo · session_01QsR2jUpJJCdztFcegijAq7
    os-dev-report

    {
      "issue": 29235,
      "status": "done",
      "branch": "claude/project-thread-k2hvaf",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29413",
      "head": "3dcde8cd",
      "session": "session_01QsR2jUpJJCdztFcegijAq7",
      "premise_still_valid": true,
      "premise_note": "Valid, and one reader more: once the sidebar asked by name, the production re-measure showed CommandPalette's navLabel (palette mounted closed in every app) still reading the whole object list in-app. Claim amended (6576916626) to add CommandPalette.tsx at the :239 hook call.",
      "summary": "The in-app sidebar (UnifiedSidebar) and the palette's nav-entry labels use useNavTargetLabel({ byName: true }) (palette via RECENT_ROW_LABELS); a dashboard target the bundle does not hold is read by name too. useRecentItemLabel reads recent dashboard, page and report rows by name. New helper useReadItemsByName (useObjectPresence.ts, beside readObjectsByName) asks each name once through the provider's getItem while the type's list is idle, and reads the list once it is loaded. Production Console, app-crm, in-app page route /apps/ops_app/page/crm_welcome: before 29 requests / 889,029 B incl. GET /meta/object 551,834 B + /meta/view 7,014 B; after 28 requests / 337,195 B, no unscoped /meta/object. Home with a recent dashboard and page: before 28 / 302,598 B incl. /meta/dashboard 5,596 B + /meta/page 15,463 B; after 28 / 284,915 B with /meta/dashboard/pipeline_dashboard 3,054 B + /meta/page/crm_welcome 1,044 B. Labels byte-identical en and zh-CN (sidebar Account/Contact/Pipeline Dashboard, 客户/联系人/销售漏斗; Home rows CRM Welcome/Pipeline Dashboard, 欢迎页/销售漏斗仪表盘).",
      "files_changed": [
        ".changeset/29235-sidebar-recents-labels-by-name.md",
        "ui/packages/app-shell/src/chrome/CommandPalette.tsx",
        "ui/packages/app-shell/src/chrome/CommandPalette.navLabelReadsByName-29235.test.tsx",
        "ui/packages/app-shell/src/hooks/useNavTargetLabel.ts",
        "ui/packages/app-shell/src/hooks/useObjectPresence.ts",
        "ui/packages/app-shell/src/hooks/useRecentItemLabel.ts",
        "ui/packages/app-shell/src/hooks/__tests__/useRecentItemLabel.readsByName-29235.test.tsx",
        "ui/packages/app-shell/src/layout/UnifiedSidebar.tsx",
        "ui/packages/app-shell/src/layout/__tests__/UnifiedSidebar.labelReadsByName-29235.test.tsx"
      ],
      "line_budget": "564 additions, 13 deletions over 9 files; 462 of the additions are the three new test files. Source: 88 added, 13 deleted. Size S holds for source.",
      "tests": "Three new files over the real MetadataProvider and a recording fake adapter: UnifiedSidebar.labelReadsByName-29235 (2, en + zh-CN), CommandPalette.navLabelReadsByName-29235 (2, closed + opened), useRecentItemLabel.readsByName-29235 (4: by-name en, zh-CN inline map + bundle key, machine name until loaded + absent asked once, CONTROL lists loaded). Ablations A1-A6 via scripts/ablation-replace.mjs, each red, each restored with git diff HEAD empty. Sweeps: 220 files / 1,797 tests at a3eaa1ec; 77 files / 642 tests at fa2a8da5; 35 files / 165 tests at 3dcde8cd. app-shell type-check 65/65 at 3dcde8cd. eslint 0 errors, hooks warning-free.",
      "gates": "dispatch-gates --commands at fa2a8da5: 34 derived, 34 run, all exit 0 (incl. node scripts/check-sdui-manifest.mjs, check:query-options-erasure, pnpm --dir ui exec vitest run scripts/ 4,903 passed, check:type-check-debt); --ran reconciled, 0 NOT-MEASURED. 3dcde8cd only merges main again (no touched file moved); check-sdui-manifest and check-changeset-no-major exit 0 there. PR-body gates with the final body: check-changeset-no-major, check-adr-0087-registration, check-closing-keyword-parity, check-partof-closing-keyword all exit 0.",
      "dogfood_battery": "n/a, no ! in the PR title and no (narrowing) arm",
      "measurement": "Playwright login + CDP Network.requestWillBeSent initiator stacks on a prod Console (objectstack dev --fresh, app-crm), runtime app ops_app with unlabelled entries; JSON in the dev scratchpad, numbers in the PR body's Verification.",
      "deviations": [
        "CommandPalette.tsx :239 hook call and its test, via claim amendment 6576916626 (found on the production re-measure).",
        "The census row openPathObjectReaders-12811 for useNavTargetLabel.ts keeps its stale prose (stays green; outside the claim's surface). Named in the PR's Acceptance notes."
      ],
      "mcp_calls": "No GitHub MCP write. Reads in the final stretch: gh api search/issues x2 (parallel-fix check for 29235, #29141 PR state).",
      "api_writes": "2 relay/stamped writes: fleet-write pr_create (PR #29413, body read back 10,613/10,613 bytes identical, no assignees) and this os-dev-report comment via post-stamped. Plus git push (not a REST write).",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "Inside a package-less app (created in the console), useNavMemberGates reads its names-only scope with views, which reads the whole /meta/view list (7,014 B on app-crm). Outside an app #29121 already passes views: false. class: observation (perf, read-only inference from the measured initiator). reach: every route of a package-less app. carrier: none",
        "A package-less app's object routes read the whole object registry from AppContent (no object scope, appObjectScope.ts). class: observation. reach: object routes of console-created apps. carrier: none",
        "A page route for a page the app bundle does not hold reads the /meta/page list (AppContent page scope, prefer-local). class: observation. reach: page routes outside the bundle. carrier: none",
        "openPathObjectReaders-12811 census row prose for useNavTargetLabel.ts is stale (still says off, reason names Home). class: drift. carrier: none"
      ],
      "dedup_terms": [
        "useNavMemberGates views",
        "package-less app object registry",
        "meta/view list in-app",
        "AppContent page scope list"
      ]
    }
  7. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m

    Landed: PR #29413 merged at 2026-11-02T15:01Z as a6441636. Fixes #29235 closed this card; pm:dispatched removed. Delivered: the in-app sidebar and the command palette label unlabelled nav entries by name (no unscoped /meta/object; an in-app page route 889,029 B → 337,195 B on app-crm), and recent dashboard, page and report rows read their item by name through useReadItemsByName instead of their type's whole list (Home with recents 302,598 B → 284,915 B). Labels unchanged in en and zh-CN. Follow-up filed: #29416 (package-less app routes and out-of-bundle page routes). Nothing left on this card.

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

Metadata

Metadata

Assignees

Labels

domain:uiDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions