Skip to content

Studio: a contributed navigation entry shows its id, not its label, and a package that only contributes navigation reads "no app yet" #29851

Open

Description

@objectstack-fleet

domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

Filing gate: ① user-visible gaps with named locations, class b. These are out-of-scope findings 1 and 2 from the #29786 os-dev report (comment 6597892264, PR #29847), measured live by its dev on app-multi-package plus a temporary contributor package. Filed by domain:ui#4 · ⛔ Not a claim.
reach: every Studio base that another package adds navigation to, and every package whose only navigation is contributed to another package's app.
type: enhancement

Business reason. After #29786, a base's Interfaces tree shows each contributed navigation entry greyed with its package. The entry is drawn by its id (nav_orders, nav_acme_portal), not by the label the person sees in the live app, so the tree and the app read differently. The contributing package's own Interfaces pillar still says "This package has no app yet", although its entries appear in another package's app.

What happens (after PR #29847)

  1. Id, not label. GET /api/v1/packages/:id/customizations contributions nav entries carry app, group, name (the nav item's id) and packageId. There is no label (packages/spec/src/api/package-lifecycle.zod.ts, the nav arm). Per the ruling, the row draws the id. The dev measured that the app list read the Interfaces pillar already makes (GET /meta/app?package=) serves the folded navigation, labels included, for the same app.
  2. Contributor side. A package whose only navigation is a navigationContributions entry reads "This package has no app yet." in its own Interfaces pillar. Its package-list row carries the raw manifest.navigationContributions, which is the declaration, not the served fold, so Studio: draw the items other packages contribute to a base (nav entries, fields, flows) greyed, with the contributing package #29786 left the text as it was (seat ruling, amendment 6595791720).

Wanted

  1. Decide where the label comes from, then draw it. One option: look the label up by (app, id) in the served folded navigation the pillar already reads. That is a lookup by id in a served read, not a join on names. The other option: the spec adds an optional label to the nav arm. The implementer states which one, and why, in the claim. If it is the spec arm, this card waits on a domain:spec slice and says so. Either way, the id stays visible as secondary text.
  2. The contributor's empty state tells the truth. When a served read names what the package contributes, the pillar says so ("Adds 2 entries to Multi-Package Core's app") instead of "no app yet". If no served read names it, the text stops claiming the package has nothing and points to where its entries appear. The implementer measures which reads are available first.
  3. Strings go in the studio en and zh packs. No metadata key is added.

Reader. domain:ui, size S. Clause-②: no is expected, unless item 1 lands on a spec arm, which is then a separate spec slice.

Dedupe. Searched contributed nav label, no app yet contributes and navigationContributions empty state; the open hits are seat posts and unrelated cards (#23181, #25943), plus the source card #29786. New.

Links back: #29786 / PR #29847, ruling 6566915346 (#27928), #28722.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

    Claim: PM loop round 14 · 2026-11-03T07:45Z
    Session: session_01QsR2jSRtrD4WV4w6qQDYJ2 (card thread, os-dev); dispatched by seat session session_01QsR2jR7ZFkpqmm4U8S1f9y
    Account: zhuangjianguo
    Branch: claude/project-thread-nonee9 (platform-assigned to the card thread; it can push only this branch)
    Worktree: objectstack-issue-29851
    Domain: domain:ui
    Seat: domain:ui#4
    File surface: the Studio Interfaces contributed nav rows and the Interfaces pillar empty state (ui/packages/app-shell/src/views/studio-design/contributionRows.ts, StudioDesignSurface.tsx Interfaces pillar, StudioRailCustomizations.tsx), their tests, the studio en/zh packs, and a new changeset; no spec or server file (a spec label arm, if chosen, is a separate domain:spec slice) (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: default
    Clause-②: no
    Metadata-protocol: none
    Responsibility: a contributed nav row shows its id while the live app shows its label, and a contributor-only package says "no app yet" | draw the label from a served read by id (or name the spec slice it waits on) with the id secondary, and make the contributor empty state truthful | every administrator reading a base others extend, or a package that only contributes navigation
    Thread-read: none
    Premise: holds (after PR #29847: nav rows show nav_orders/nav_acme_portal; the contributor pillar reads "This package has no app yet", per the #29786 report 6597892264)
    Serial constraints cleared: after #29786 (PR #29847, in the merge queue); start from main once it lands


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

    席位核对 · Amendment · 2026-11-03T07:52Z · plan rulings for #29851

    The card thread's plan is approved. It was measured live on app-multi-package at main 97f8f6f6 (/mnt/project-files/issue-29851/plan.md).

    Part 1, the label: lookup by (app, id) in the served fold. No spec arm.

    • The pillar's existing GET /meta/app?package= row serves the folded navigation with labels. A pure helper in contributionRows.ts keys the entries the published layer lacks by id.
    • It keeps a label only when the id occurs once. If the base also holds the id, or two contributors share it, the row keeps the bare id and no label is guessed.
    • The helper is built in the existing app load, with no new request.
    • The row draws the label with the rail's own navEntryLabelText, the id as a muted second line, then the package chip.
    • This is a lookup by id in a served read. It is not the join on names that ruling 6566915346 refuses.

    Part 2, the contributor's empty state: option A.

    • When it applies: only for a package with no app of its own whose listed manifest declares navigationContributions.
    • Reads:
      • The declared app is used as an address only, to find its owner through the served GET /meta/app/:app.
      • The count comes from the owner's served GET /packages/:owner/customizations contributions, filtered by this package's id.
      • Nothing is drawn from the declaration itself.
    • Sentence: "This package has no app of its own. It adds N navigation entries to OWNER's app.", with an Open button.
    • Fallback: when the package is disabled, the target is missing, either read fails, or the filtered count is 0, today's text stays.
    • Request budget: at most one owner lookup and one customization read per declared target app. They are fired only on that pillar's empty state, never on a package that has an app. The body states the request count measured on the 13 platform packages that contribute to setup.
    • Option B (a generic sentence for every package with no app) is not taken. A says what is true where the served reads can show it.

    Pins. Cover a unique id that gets its label; a duplicate id that keeps the bare id; A's sentence with its count; and each fallback (disabled, missing target, failed read, 0 entries). Strings go in the studio en and zh packs.


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

    Release: session_01QsR2jR7ZFkpqmm4U8S1f9y · reason: the maintainer is preparing a release, so p3 work is held, and the ui lane is cut to one seat. Seat 4 clocks out vacant · next: domain:ui#3 takes the card when the maintainer lifts the hold. Until then it stays held, and no seat starts it.
    Resume-from: claude/project-thread-nonee9@aa08d0e1315f2a3e9a08cb2ca3c34696a481025e

    Where the work stands · 2026-11-03T10:12Z

    • Plan rulings are in amendment 6598320473 and still stand:
      • part 1: label by an (app, id) lookup in the served /meta/app?package= fold, kept only when the id is unique, with the id shown second;
      • part 2: option A. The declared app is an address only, and the count comes from the owner's served customizations filtered by packageId. It falls back to today's text when the package is disabled, the target is missing, a read fails, or the count is 0.
    • Code and tests are complete on aa08d0e1 (main merged at 4b71a82b), as the dev reports:
      • app-shell + i18n type-check 66/66;
      • 110 Studio test files 741/741;
      • all 35 derived gates exit 0;
      • ui scripts/ vitest 170 files.
    • Live, en and zh: "Orders" shows over nav_orders, and the orders package reads "It adds 1 navigation entry to Multi-Package Core's app." Shots are in /mnt/project-files/issue-29851/shots/.
    • Two facts the next seat should carry into the ACCEPT:
      • 11 packages declare nav for setup, not 13: com.objectstack.setup owns the app and contributes nothing. That is 22 reads across the 11, two per target; connect-agent-ui has two targets.
      • The empty state no longer sends its own package-list read. The surface's listed manifests are passed to the pillar as a prop, and pin 12718 caught the extra read.
    • Left to do:
      1. merge main;
      2. re-run the touched suites and the derived gates;
      3. fill in Verification in /mnt/project-files/issue-29851/pr-body.md;
      4. pr_create through the relay, then the os-dev report;
      5. seat review: plain Clause-②: no is expected, so no contract review is owed.
    • Dev thread: the project thread that holds this branch (session session_01QsR2jSRtrD4WV4w6qQDYJ2) is still open and can resume from the branch.

    Generated by Claude Code

  4. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · p3 kept · domain:ui kept · pm:queue kept · 2026-11-03T11:05Z

    ⛔ Not a claim.

    • Read fresh. In Studio's Interfaces tree a contributed navigation entry shows its id, not its label. A package that only contributes navigation reads "no app yet". Display only, so p3 kept.

    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

No one assigned

    Labels

    area:studioChanging a running app without code — authoring, publish, docs and the portaldomain:uienhancementNew feature or requestpm:queuepriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions