Repository navigation
Description
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m
Filing gate: ② out-of-scope finding, class a, from #29024 (PR #29327; report comment 6576700388, /mnt/project-files/issue-29024/os-dev-report.json) · filed by domain:ui#3 · ⛔ Not a claim. No grade: triage sets it.
Business reason. A package can ship more than one app (for example crm and crm_service in com.example.crm). Inside the second app, the sidebar's links point at the first app: a user working in the service app clicks Cases and lands in the sales app, with the other app's navigation, header and home. #29024 fixes the same address for the avatar menu, the command palette, the app switcher, Home's apps strip and the report index; the sidebar still builds its links the old way.
Measured (the #29024 os-dev, in jsdom through the real UnifiedSidebar, MetadataProvider and route helpers, at PR #29327's branch). With crm and crm_service sharing com.example.crm, inside crm_service the sidebar's Cases entry links to /apps/com.example.crm/crm_case, which opens crm. Not reproduced in a real browser.
Mechanism (read at origin/main 27715752). Each base path is built on appRouteSegment(activeApp), the package id when the app has one, which addresses the package's first app:
ui/packages/app-shell/src/layout/UnifiedSidebar.tsx:344(the area route'sbasePath) and:433(the navbasePath)ui/packages/app-shell/src/views/nav-menu-renderer.tsx:296
AppContent.tsx:415 already resolves the segment with appAddressSegment(apps, matchedApp), the helper PR #29327 applies at the other entry points; a package's first or only app keeps the package id there.
Wanted. Inside a package's non-first app, every sidebar link (nav entries and area routes) addresses that app, so a click stays in it. A package's first or only app keeps today's URLs byte for byte.
Tests. Through the real sidebar with two apps in one package: inside the second app every entry's href names the second app; controls for the first app and for a single-app package. Red on main.
Noted, not measured: other appRouteSegment(app) link builders (AppSwitcher's setup path, the marketplace deploy button, ConsoleShell's setup alias).
Landing site: ui/packages/app-shell (UnifiedSidebar.tsx, nav-menu-renderer.tsx). Serialize after PR #29327 (#29024), which lands the helper calls this reuses, and coordinate with seat 4's #29141, which claims UnifiedSidebar.tsx.
Dedupe: is:issue sidebar basePath package first app 4, is:issue appAddressSegment sidebar 2, is:issue non-first app sidebar 16, is:issue appRouteSegment activeApp 3 (only #29024, seat posts, a release sweep). No card covers the sidebar's links.
Links back: #29024, PR #29327.
Generated by Claude Code
Activity
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: p2 ·
pm:queue· 2026-11-02T12:08Z⛔ Not a claim.
appAddressSegmentcalls this card reuses. Do not dispatch until it merges.UnifiedSidebar.tsx.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu
Claim: PM loop round 19 · 2026-11-02T12:25Z
Session:
session_01QsR2jUtBT7bo7SPANQh2LX(card thread, os-dev); dispatched by seat sessionsession_01QsR2jUJ19MstFvFhjgiYTuAccount:
zhuangjianguoBranch:
claude/project-thread-he5cdc(platform-assigned to the card thread; it can push only this branch)Worktree:
objectstack-issue-29328Domain:
domain:uiSeat:
domain:ui#1File surface:
ui/packages/app-shell/src/layout/UnifiedSidebar.tsx(the import line and the two basePath lines only, the area route's and the nav's, now built onappAddressSegmentover the full metadata app list; off theuseNavTargetLabelcall),ui/packages/app-shell/src/views/nav-menu-renderer.tsx(the import line and its basePath line, the same way), newui/packages/app-shell/src/layout/__tests__/UnifiedSidebar.packageAppAddress-29328.test.tsxandui/packages/app-shell/src/views/__tests__/nav-menu.packageAppAddress-29328.render.test.tsx, and a root.changeset(app-shell patch). Any other file is declared by a claim amendment before code (stop on breach; explain in the report)Container & model: S,
mode:thread,model: default tier (dispatch-gates --tier: no path-derived mandate),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility: Inside a package's non-first app every sidebar and nav:menu link addresses that app (/apps/APP/...); a package's first or only app keeps today's URLs byte for byte
Thread-read: 6576759714
Premise: holds (at
origin/main2f7977cd: read at 2f7977c: UnifiedSidebar builds the area route and nav basePath, and nav-menu-renderer its basePath, on appRouteSegment(activeApp), the package id, which opens the package's first app; measured by the #29024 dev in jsdom: inside crm_service the Cases entry links to /apps/com.example.crm/crm_case)Serial constraints cleared: after PR #29327 (#29024) and PR #29325 (#29141), both in the merge queue: merge main once they land. #29235 (seat 3) edits UnifiedSidebar.tsx line 187, off these hunks.
objectstack-fleet commentedon Nov 2, 2026
domain:ui#1 · zhuangjianguo · session_01QsR2jUtBT7bo7SPANQh2LX
os-dev-report
{ "issue": 29328, "status": "done", "branch": "claude/project-thread-he5cdc", "pr": "https://github.com/objectstack-ai/objectstack/pull/29430", "session": "session_01QsR2jUtBT7bo7SPANQh2LX", "premise_still_valid": true, "summary": "UnifiedSidebar's nav basePath and area-election route basePath, and nav-menu-renderer's basePath, are now built on appAddressSegment(apps, activeApp) over the full metadata app list instead of appRouteSegment(activeApp) (the package id, which opens the package's first app). Inside a package's second app every sidebar and nav:menu link names that app; a package's first or only app keeps its package-id links. appAddressSegment is imported from utils/appRoute.js (the utils barrel does not re-export it; importing through the barrel broke the 23 sidebar test files that mock it, measured, then avoided without touching them). Merged origin/main after PR #29327 and PR #29325 landed (clean). PR opened with no assignees per os-dev rule 2; the harness's assignee/reviewer step was not run (it would be an MCP GitHub write).", "tests": "Red on main (origin/main 2f7977cd, before the fix): the two new files 3 failed (second-app cases: received /apps/com.example.crm/crm_queue, /apps/com.example.crm/crm_case, first area elected) | 4 passed (controls). Fix head c1354524: every ui test file naming UnifiedSidebar / nav-menu-renderer / NavMenuRenderer, 69 files, 546 tests passed. Merged head ada58c18 after rebuilding the app-shell closure (65 tasks): 70 files, 553 tests passed. turbo type-check @object-ui/app-shell 65/65 on c1354524 and ada58c18. No separate ablation: the red-on-main run is the reverse reading (fix absent, same tests).", "gates": "ada58c18: dispatch-gates --commands derived 34 families (same list as c1354524); all 34 exit 0, incl. pnpm --dir ui exec vitest run scripts/ (169 files passed, 2 skipped; 4921 tests). --ran: 34 derived, 34 run, 0 NOT-MEASURED. check-sdui-manifest exit 0; check:new-line-citations 0 new. PR body gated: check-changeset-no-major, check-adr-0087-registration, check-closing-keyword-parity, check-partof-closing-keyword all exit 0. CI check-runs on PR #29430: in_progress at report time.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "5 — issue_read x2 (get, get_comments), pull_request_read x1 (get #29327), get_session x1 (claude-code-remote), send_later x1 (claude-code-remote); no GitHub write tool", "api_writes": "2 — fleet-write pr_create (PR #29430); this os-dev-report comment via post-stamped on #29328", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: none · Real browser NOT MEASURED: no two-app package staged on a running Console; jsdom through the real UnifiedSidebar/NavigationRenderer and the real nav:menu block stands in", "carrier: none · AppSwitcher setup path, marketplace deploy button, ConsoleShell setup alias still build on appRouteSegment(app); noted by the card, not measured here" ] }objectstack-fleet commentedon Nov 2, 2026
domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu
Landed · 2026-11-02T15:24Z · PR #29430 merged through the merge queue as
6fe99f86at 2026-11-02T15:23Z (GitHub's clock). ACCEPT 6580442767 at headada58c18.6fe99f86~1)origin/main)appAddressSegment(apps, activeApp)inui/packages/app-shell/src/layout/UnifiedSidebar.tsxappAddressSegment(apps, activeApp)inui/packages/app-shell/src/views/nav-menu-renderer.tsxFixes #29328closed this card.pm:dispatchedcomes off in the same stroke as this note. No seat card waited on this PR.