You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
console: the dashboard route reads its dashboard from the app bundle, so an app's dashboard open stops reading the /meta/dashboard list #28784
Filing gate: ① console performance gap, measured · found by the #28645 / #28680 os-dev (out-of-scope finding, PR #28783 report 6562864580) · filed by domain:ui#1 · ⛔ Not a claim.
Business reason.#28645 moved an app page's view, page and nav-dashboard reads to the app bundle, and #28680 (PR #28783) retired the navigation diff that read the page and dashboard lists. The dashboard route is the one app route left that still reads a whole per-type list the bundle already holds: every open of /apps/APP/dashboard/NAME reads GET /api/v1/meta/dashboard.
Measured (warm reload, production build, showcase_app, the #28783 dev). Dashboard route 35 on main before #28645 → 35 after PR #28754 → 34 with PR #28783. The expected 33 is not reached because the route still waits for the dashboard list; the retired effect only shared that request. The page route went 26 → 24 the same way PR #28754 made it bundle-first.
Located (origin/main8afaf12d).
ui/packages/app-shell/src/console/appRouteMetadataReads.ts:61: { path: 'dashboard/:dashboardName', reads: ['dashboard', 'object'] }, so AppContent's route gate (routeReads, AppContent.tsx:433 / :496-501) waits for the whole dashboard bucket.
ui/packages/app-shell/src/views/DashboardView.tsx resolves its dashboard from that list.
Wanted. The dashboard route reads its dashboard bundle-first, the way the page route does, and drops the dashboard bucket from its route gate. The list is read only for a name outside the bundle, prefer-local kept. The object read the route needs for the widgets is unchanged. A pin shows a bundled dashboard opens with no /meta/dashboard request; the measurement goes in the PR body (expected 34 → 33).
Reader.domain:ui, through triage. Size S/M; p3 like #28645.
Dedup.dashboard bundle route and meta/dashboard list read → only #28645 and #28680 (this card's parents).
本卡正文写明「The object read the route needs for the widgets is unchanged」。建议把 object 桶一并改成「应用 bundle 里的对象 + 剪枝」(bundle 已含应用包的对象;包外对象按 record 路由的按名规则),否则仪表盘仍要等整表。秒数受当天本机链路影响(CF 边缘静态文件 65 KB/s),这里引用的是请求先后关系。
Read fresh against main. On main, ui/packages/app-shell/src/console/appRouteMetadataReads.ts line 61 still gates dashboard/:dashboardName on ['dashboard','object'], so DashboardView reads the whole /meta/dashboard list. The latest comment's measurement says the object bucket is the larger wait and asks the dev to consider moving it too. That is a scope note for the dev, not a question for the maintainer. The card was already routed and graded but carried only finding, which no lane's queue query reads. Its priority and lane are unchanged.
Claim: PM loop round 19 · 2026-11-02T11:19Z
Session: session_01QsR2jVVA94oekr4rqqQgUJ (card thread, os-dev); dispatched by seat session session_01QsR2jUJ19MstFvFhjgiYTu
Account: zhuangjianguo
Branch: claude/project-thread-9lsrc1 (platform-assigned to the card thread; it can push only this branch)
Worktree: objectstack-issue-28784
Domain: domain:ui
Seat: domain:ui#1
File surface: ui/packages/app-shell/src/views/DashboardView.tsx (reads its dashboard bundle-first via useBundledItem, the meta/dashboard list prefer-local only on a miss, refusal probe unchanged; hides a widget whose object the scope answered missing, a hand-rolled context keeps the whole list), ui/packages/app-shell/src/console/AppContent.tsx (the dashboard route drops the dashboard bucket when bundle reads exist, as pageRouteReadsBundle, and hands readAppObjectScope a bundle-first dashboard reader), ui/packages/app-shell/src/console/appObjectScope.ts (dashboard/:dashboardName joins APP_OBJECT_SCOPE_ROUTES: package list plus the widgets' objects by name via a new dashboardObjectNames(), the app's requiresObject entries and palette names when open, through readObjectScope({packageId, names}); never the whole registry), ui/packages/app-shell/src/console/appRouteMetadataReads.ts (comment only), ui/packages/app-shell/src/console/__tests__/openPathObjectReaders-12811.test.ts (the DashboardView row), a new ui/packages/app-shell/src/console/__tests__/AppContent.dashboardRouteReads-28784.test.tsx, and a root .changeset (app-shell patch). Existing DashboardView*.test.tsx pins move only by a claim amendment; any other file is declared by a claim amendment before code (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: A bundled dashboard route opens from the app bundle with no meta/dashboard read and no unscoped meta/object read; its object read is scoped to the package plus the widgets' objects by name; a widget whose object the scope answered missing is hidden
Thread-read: 6572239930
Premise: holds (at origin/main9f120af9: the dev measured at 39951d2 (prod console, showcase_ops_dashboard, warm reload x3): 32 /api/ requests; the route reads meta/object whole (746,514 B), meta/view (24,009 B) and meta/dashboard (12,075 B) after the bundle, and the 9 dataset queries start only after them; expected 32 to 30)
Serial constraints cleared: none known.
{
"issue": 28784,
"status": "done",
"branch": "claude/project-thread-9lsrc1",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29472",
"session": "session_01QsR2jVVA94oekr4rqqQgUJ",
"premise_still_valid": true,
"summary": "The dashboard route reads its dashboard bundle-first (DashboardView via useBundledItem; the meta/dashboard list prefer-local only on a miss) and AppContent drops the dashboard bucket when bundle reads exist. dashboard/:dashboardName joins APP_OBJECT_SCOPE_ROUTES: the route reads the app package list plus, by name, the widgets' requiresObject/object names (readDashboardWidgetObjects, views:false), the app's requiresObject entries and palette names; never the whole registry. The widget prune hides a widget whose object the scope answered missing; a hand-rolled context keeps the whole list. readObjectsByName was not needed. Production showcase, same base 96fb7b5d: 32 -> 30 requests; meta/dashboard (12,075 B), whole meta/object (746,514 B) and meta/view (24,009 B) gone, meta/object?package= (157,802 B) added; first dataset query 1709/1135/1006 ms -> 1654/1032/885 ms on localhost (the bundle remains the route's longest wait locally).",
"tests": "New AppContent.dashboardRouteReads-28784.test.tsx 3/3 (real MetadataProvider + AppContent + DashboardView, recorded reads, controlled bundle). 108 app-shell files naming the touched modules: 878 tests passed. app-shell type-check exit 0. Ablations via ablation-replace.mjs, each restored (git diff HEAD empty): A1 route gate keeps dashboard bucket -> (a)(b) red; A2 ignore bundle hit -> (a)(b) red; A3 route off APP_OBJECT_SCOPE_ROUTES -> (a)(b)(c) red; A4 prune ignores missing -> (b) red. First A4 run also redded (a) by a lazy-chunk race; fixed by importing DashboardView at module scope, rerun clean.",
"gates": "dispatch-gates --commands at ae3d70fb: 34 derived, 34 run, all exit 0; --ran reconciled, 0 NOT-MEASURED. check:type-check-debt and ui vitest scripts/ (169 passed, 2 skipped) under the lock. eslint --no-inline-config on changed files 0 errors; check:new-line-citations 0 new; ui check:spec-symbols exit 0. PR body gates (changeset-no-major, adr-0087-registration, closing-keyword-parity, partof-closing-keyword) exit 0 on the sent body. PR check-runs: in_progress at report time.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "6 — issue_read x3, pull_request_read x2 (#29229 get/get_files), get_session x1; no write tool",
"api_writes": "2 — fleet-write pr_create (#29472); post-stamped issue comment on #28784",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: none · noted, not filed: design/dashboard/:dashboardName and the search route still read the meta/dashboard list (noted in Acceptance notes)"
]
}
Landed · 2026-11-02T16:24Z · PR #29472 merged through the merge queue as 94d3e254 at 2026-11-02T16:23Z (GitHub's clock). ACCEPT 6581958673 at head ae3d70fb.
probe
before (94d3e254~1)
now (origin/main)
useBundledItem('dashboard' in ui/packages/app-shell/src/views/DashboardView.tsx
0
1
'dashboard/:dashboardName' in APP_OBJECT_SCOPE_ROUTES (ui/packages/app-shell/src/console/appObjectScope.ts)
0
1
Fixes #28784 closed this card. pm:dispatched comes off in the same stroke as this note. No seat card waited on this PR. The designer route (design/dashboard/:dashboardName) and search still read the dashboard list, as the PR body records.
Activity
objectstack-fleet commentedon Nov 2, 2026
coordinator#1 · hotlong · session_6eb9ec2e0e3f410b91239dab7a337b9e
补一组读数:仪表盘路由要等的大头是整个对象注册表,不是 dashboard 列表(2026-11-02T07:56Z)
staging,cloud main
cd4e2e1f(objectstack pin6cbdef1e),环境os-2ph4c1(HotCRM 6.0.0),高管仪表盘/apps/app.objectstack.hotcrm/dashboard/executive_dashboard整页打开的 resource timing(ms,start → end):GET /api/v1/meta/object(无?package=,整表)3397 → 7022GET /api/v1/meta/app/crm_enterprise/bundle3414 → 7054GET /api/v1/meta/dashboard3412 → 4632POST /api/v1/analytics/dataset/query在 7258–7259 才一起发出(→ 8781–9272)十个图表查询要等整表和 bundle 都返回(
routeReadsSettled)。原因:appRouteMetadataReads.ts:61给dashboard/:dashboardName的路由读是['dashboard','object'],而仪表盘路由不在appObjectScope.ts:116-120的范围名单里,AppContent.tsx:502-509的routeReadsKey因此保留object桶,ensureType('object')读整表;DashboardView.tsx:179再从objects取名字剪枝 widget。本卡正文写明「The
objectread the route needs for the widgets is unchanged」。建议把object桶一并改成「应用 bundle 里的对象 + 剪枝」(bundle 已含应用包的对象;包外对象按 record 路由的按名规则),否则仪表盘仍要等整表。秒数受当天本机链路影响(CF 边缘静态文件 65 KB/s),这里引用的是请求先后关系。来源:维护者在会话里要求评估核心页面性能并「使用 fable 评估后立卡」,审核会话判定这一条评论到本卡、不另立。
🤖 Generated with Claude Code
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: finding →
pm:queue· 2026-11-02T08:09Z⛔ Not a claim.
main. On main, ui/packages/app-shell/src/console/appRouteMetadataReads.ts line 61 still gates dashboard/:dashboardName on ['dashboard','object'], so DashboardView reads the whole /meta/dashboard list. The latest comment's measurement says the object bucket is the larger wait and asks the dev to consider moving it too. That is a scope note for the dev, not a question for the maintainer. The card was already routed and graded but carried onlyfinding, which no lane's queue query reads. Its priority and lane are unchanged.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu
Claim: PM loop round 19 · 2026-11-02T11:19Z
Session:
session_01QsR2jVVA94oekr4rqqQgUJ(card thread, os-dev); dispatched by seat sessionsession_01QsR2jUJ19MstFvFhjgiYTuAccount:
zhuangjianguoBranch:
claude/project-thread-9lsrc1(platform-assigned to the card thread; it can push only this branch)Worktree:
objectstack-issue-28784Domain:
domain:uiSeat:
domain:ui#1File surface:
ui/packages/app-shell/src/views/DashboardView.tsx(reads its dashboard bundle-first via useBundledItem, the meta/dashboard list prefer-local only on a miss, refusal probe unchanged; hides a widget whose object the scope answered missing, a hand-rolled context keeps the whole list),ui/packages/app-shell/src/console/AppContent.tsx(the dashboard route drops thedashboardbucket when bundle reads exist, as pageRouteReadsBundle, and hands readAppObjectScope a bundle-first dashboard reader),ui/packages/app-shell/src/console/appObjectScope.ts(dashboard/:dashboardNamejoins APP_OBJECT_SCOPE_ROUTES: package list plus the widgets' objects by name via a new dashboardObjectNames(), the app's requiresObject entries and palette names when open, through readObjectScope({packageId, names}); never the whole registry),ui/packages/app-shell/src/console/appRouteMetadataReads.ts(comment only),ui/packages/app-shell/src/console/__tests__/openPathObjectReaders-12811.test.ts(the DashboardView row), a newui/packages/app-shell/src/console/__tests__/AppContent.dashboardRouteReads-28784.test.tsx, and a root.changeset(app-shell patch). Existing DashboardView*.test.tsx pins move only by a claim amendment; any other file is declared by a claim amendment before code (stop on breach; explain in the report)Container & model: M,
mode:thread,model: default tier (dispatch-gates --tier: no path-derived mandate),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility: A bundled dashboard route opens from the app bundle with no meta/dashboard read and no unscoped meta/object read; its object read is scoped to the package plus the widgets' objects by name; a widget whose object the scope answered missing is hidden
Thread-read: 6572239930
Premise: holds (at
origin/main9f120af9: the dev measured at 39951d2 (prod console, showcase_ops_dashboard, warm reload x3): 32 /api/ requests; the route reads meta/object whole (746,514 B), meta/view (24,009 B) and meta/dashboard (12,075 B) after the bundle, and the 9 dataset queries start only after them; expected 32 to 30)Serial constraints cleared: none known.
objectstack-fleet commentedon Nov 2, 2026
domain:ui#1 · zhuangjianguo · session_01QsR2jVVA94oekr4rqqQgUJ
os-dev-report
{ "issue": 28784, "status": "done", "branch": "claude/project-thread-9lsrc1", "pr": "https://github.com/objectstack-ai/objectstack/pull/29472", "session": "session_01QsR2jVVA94oekr4rqqQgUJ", "premise_still_valid": true, "summary": "The dashboard route reads its dashboard bundle-first (DashboardView via useBundledItem; the meta/dashboard list prefer-local only on a miss) and AppContent drops the dashboard bucket when bundle reads exist. dashboard/:dashboardName joins APP_OBJECT_SCOPE_ROUTES: the route reads the app package list plus, by name, the widgets' requiresObject/object names (readDashboardWidgetObjects, views:false), the app's requiresObject entries and palette names; never the whole registry. The widget prune hides a widget whose object the scope answered missing; a hand-rolled context keeps the whole list. readObjectsByName was not needed. Production showcase, same base 96fb7b5d: 32 -> 30 requests; meta/dashboard (12,075 B), whole meta/object (746,514 B) and meta/view (24,009 B) gone, meta/object?package= (157,802 B) added; first dataset query 1709/1135/1006 ms -> 1654/1032/885 ms on localhost (the bundle remains the route's longest wait locally).", "tests": "New AppContent.dashboardRouteReads-28784.test.tsx 3/3 (real MetadataProvider + AppContent + DashboardView, recorded reads, controlled bundle). 108 app-shell files naming the touched modules: 878 tests passed. app-shell type-check exit 0. Ablations via ablation-replace.mjs, each restored (git diff HEAD empty): A1 route gate keeps dashboard bucket -> (a)(b) red; A2 ignore bundle hit -> (a)(b) red; A3 route off APP_OBJECT_SCOPE_ROUTES -> (a)(b)(c) red; A4 prune ignores missing -> (b) red. First A4 run also redded (a) by a lazy-chunk race; fixed by importing DashboardView at module scope, rerun clean.", "gates": "dispatch-gates --commands at ae3d70fb: 34 derived, 34 run, all exit 0; --ran reconciled, 0 NOT-MEASURED. check:type-check-debt and ui vitest scripts/ (169 passed, 2 skipped) under the lock. eslint --no-inline-config on changed files 0 errors; check:new-line-citations 0 new; ui check:spec-symbols exit 0. PR body gates (changeset-no-major, adr-0087-registration, closing-keyword-parity, partof-closing-keyword) exit 0 on the sent body. PR check-runs: in_progress at report time.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "6 — issue_read x3, pull_request_read x2 (#29229 get/get_files), get_session x1; no write tool", "api_writes": "2 — fleet-write pr_create (#29472); post-stamped issue comment on #28784", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: none · noted, not filed: design/dashboard/:dashboardName and the search route still read the meta/dashboard list (noted in Acceptance notes)" ] }objectstack-fleet commentedon Nov 2, 2026
domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu
Landed · 2026-11-02T16:24Z · PR #29472 merged through the merge queue as
94d3e254at 2026-11-02T16:23Z (GitHub's clock). ACCEPT 6581958673 at headae3d70fb.94d3e254~1)origin/main)useBundledItem('dashboard'inui/packages/app-shell/src/views/DashboardView.tsx'dashboard/:dashboardName'inAPP_OBJECT_SCOPE_ROUTES(ui/packages/app-shell/src/console/appObjectScope.ts)Fixes #28784closed this card.pm:dispatchedcomes off in the same stroke as this note. No seat card waited on this PR. The designer route (design/dashboard/:dashboardName) andsearchstill read the dashboard list, as the PR body records.