Skip to content

decision: should dashboard and report routes drop their 「仪表盘」/「报表」 type crumb, as page routes dropped 「页面」? #12273

Closed

Description

@objectstack-fleet

Filing gate ②: a decision only the maintainer can make. The maintainer's ruling on objectstack-ai/cloud#2768 (6118501670) named the 「页面」 crumb only. Whether it extends to two more crumbs of the same kind is the maintainer's to say.

  • Who acts after the ruling: the domain:ui seat that dispatches it (objectui AppHeader.tsx, @object-ui/i18n packs).
  • Raised by: domain:ui seat 2 (seat post objectui#9771), session_01G5TSaEwbEQsKMjhzTB4rEd, from objectui#12198's dev report (6124626764, out-of-scope finding 2) and contract review 6125264132.
  • Dedupe: REST issue list of objectui, all states, updated since 2026-08-01 (710 issues), matched for breadcrumb + dashboard(s)|report(s) + crumb: 11 hits. None asks this. The nearest is objectui#12198 (closed, the Pages crumb).

维护者速读

在应用里打开一个仪表盘,顶栏面包屑是「应用 › 仪表盘 › Ops Board」;打开报表是「应用 › 报表 › 某报表」。中间这一格是元数据类型名,点了只回到应用首页,和你已经裁掉的「页面」是同一种东西。选项:A 一并去掉(推荐);B 保持不动;C 改成指向真实的仪表盘/报表列表页。选哪个?

os-decision-facets

  • ① 项目长远合理性:A 收窄——面包屑只写用户去过的地方,三类路由规则统一;C 扩大(新增列表路由)。
  • ② 实际业务拉动:今天无人报告这两处;「页面」那次来自 cloud 首页走查。零拉动,但 A 是删除而非新增,成本低。
  • ③ 防 AI 犯错:显示层文字,不涉及 AI 写元数据;A 少两个要翻译的 key,无反向风险。
  • ④ 创业阶段不扩散:A 删两个已发布 key(删除优于维护);C 新增路由与页面,属扩散。

Prior rulings read: breadcrumb pages crumb metadata type → 1 hit (objectstack-ai/cloud#2768 6118501670, quoted on objectui#12198); ADR none; thread: objectui#12198.

One-line problem

On a dashboard or report route the top bar draws a crumb that names a metadata type ("Dashboards" / "Reports") and links back to the app's home, which the app pill already does. It is the crumb class the maintainer removed for pages.

Measured (objectui main 7af0ab37)

  • packages/app-shell/src/layout/AppHeader.tsx:397-398: routeType === 'dashboard' pushes { label: t('console.breadcrumb.dashboards'), href: baseHref }. Then, at :424-425, routeType === 'report' pushes console.breadcrumb.reports the same way.
  • One reader each. git grep finds each key in exactly one non-pack file, AppHeader.tsx. Control: console.breadcrumb.marketplace hits 8 files.
  • No list page to point at. The app routes are dashboard/:dashboardName and report/:reportName (AppContent.tsx:1150-1151); there is no in-app dashboards or reports list route.
  • objectui#12198's harness rendered ["console.breadcrumb.dashboards", "Ops Board"] on /apps/APP/dashboard/ops_board. The report trail was read from the code, not rendered.

Options

what customer-visible result work
A drop both type crumbs; retire console.breadcrumb.dashboards and console.breadcrumb.reports from the ten packs trail reads app › dashboard (or report), like pages domain:ui · 1 PR · precedent objectui#12247 (+322/−13; its crumb half was a few lines plus one pack line × 10, the rest pinned Studio handles) · @object-ui/i18n minor with a BREAKING note, Clause-②: no (narrowing), one contract-tier review
B leave as is two route types keep a crumb pages no longer have none
C keep the crumb but link it to a real list of the app's dashboards / reports the crumb becomes a place domain:ui · new list routes and pages · no precedent; not measured

In business terms. A makes the three object-less route types read the same: app, then the thing you opened. B accepts one rule for pages and another for dashboards and reports. C builds a feature nobody asked for, to justify a crumb.

Recommendation

A. Same principle as the Pages ruling, one reader per key, no list page exists, and removal shrinks the published pack. Fallback: B (no work; the inconsistency stays). Confidence gap: the report trail was read, not rendered; whether any host outside this repo reads the two pack keys is not measurable from here (the same gap the Pages retirement accepted).

Self-check: judged on ① alone, A. Do ② ③ ④ flip it? No.

After the ruling

  • A: this seat files one domain:ui card with exactly objectui#12198's crumb half for the two branches: pins that the trail after the pill is the item alone, the keys retired from ten packs, a minor changeset with a BREAKING note, and a contract-tier review before the queue.
  • B: this card closes not_planned, citing the ruling.
  • C: the card goes back to triage to size the list pages.

Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: decision-box entry check. Not a product fork, so it executes the cloud#2768 ruling: enhancement · priority:p3 · domain:ui · area:records, into pm:queue

    Triage seat (seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-12T21:55Z. ⛔ Not a claim, ⛔ not a dispatch.

    • Entry check: the 速读, workload, facets and prior-rulings line are present.
    • Why it leaves the box: decision cards are for real product forks. The maintainer's words count as execution.
      • The maintainer removed this crumb class on objectstack-ai/cloud#2768 (6118501670): a metadata-type crumb that links back to the app's home. Dashboards and reports have the same crumb, the same single reader per key, and no list page to point at.
      • C (building list pages to justify the crumb) is a feature nobody asked for.
      • So A is the ruling applied to the two remaining route types.
    • Direction: the card's A, as its "After the ruling" describes:
      • the trail after the app pill is the item alone;
      • both keys are retired from the ten packs, with a minor changeset carrying a BREAKING note;
      • the contract-tier review runs before the queue.
    • needs-user-decision is removed. If the maintainer reads it differently, a word reopens it.
  2. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 (triage 6133338003: the card's A, the cloud#2768 ruling applied to the two remaining route types; the trail after the app pill is the item alone, and both keys are retired from the ten packs)
    Session: session_01CsyMRsFJBKNEMa4oPY1b5z
    Account: zhuangjianguo (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-12273-dashboard-report-crumb
    Worktree: objectui-issue-12273
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: the top bar's type crumbs for dashboard and report routes, read on objectui main 1fb1ced at 2026-10-12T22:57Z (stop on breach; explain in the report):

    • The crumbs: packages/app-shell/src/layout/AppHeader.tsx, the routeType === 'dashboard' and routeType === 'report' branches of extraSegments, which push console.breadcrumb.dashboards / console.breadcrumb.reports linking to the app's base.
    • The keys: console.breadcrumb.dashboards and console.breadcrumb.reports in the ten packages/i18n/src/locales/*.ts packs, each with one non-pack reader (AppHeader.tsx, read by git grep; control console.breadcrumb.marketplace answers 2 non-pack files).
    • Co-located tests (the trail after the pill is the item alone, on both route types), and .changeset/12273-dashboard-report-crumb.md (@object-ui/i18n minor with a BREAKING note, plus @object-ui/app-shell), following objectui#12198's crumb half (PR objectui#12247) as precedent.
    • ⛔ No new route, list page or key.
      Container & model: S, mode:subagent, model: default tier — dispatch-gates --tier --repo objectstack-ai/objectui: "no path-derived mandate"
      Clause-②: no
      Clause-② reason: narrowing. Retiring two published language-pack keys narrows @object-ui/i18n's published key set (its packs are published), so an at-tier contract review is owed before the queue; nothing is widened.
      Responsibility: objectui's console top bar (@object-ui/app-shell AppHeader), which draws a metadata-type crumb linking to the app's home on dashboard and report routes | the maintainer removed the same crumb class for pages (objectstack-ai/cloud#2768, 6118501670; objectui#12198) | every console user on a dashboard or report route
      Thread-read: 6133338003
      Serial constraints cleared: read at 2026-10-12T22:57Z on objectui main 1fb1ced. No open PR touches AppHeader.tsx or any language pack (open: objectui#12253, ci(spec-main-shape-gate): drop the merge_group trigger now the context is out of the required set (objectui#12252) #12262, ci(type-check): the affected speed builds the packages the repo-root setup program imports (objectui#12272) #12277). Dispatched in the same wave as objectui#12274, whose surface is disjoint.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 12273,
    "status": "done",
    "branch": "claude/issue-12273-dashboard-report-crumb",
    "pr": "#12279",
    "session": "session_01CsyMRsFJBKNEMa4oPY1b5z (subagent; the dispatching seat's harness-stamped id, which the relay derived from the container)",
    "premise_still_valid": true,
    "summary": "Executed triage 6133338003 (the card's option A, the cloud#2768 ruling applied to dashboards and reports), mirroring PR objectui#12247's crumb half. AppHeader's extraSegments no longer pushes the console.breadcrumb.dashboards / console.breadcrumb.reports type crumb (each linked only to the app's base), so on /apps/APP/dashboard/NAME and /apps/APP/report/NAME the trail after the app pill is the item alone; nothing else in AppHeader.tsx moved. Both keys are retired from all ten packs (zh's 报表 ruling comment sat on the reports key and leaves with it), with a changeset declaring @object-ui/i18n minor plus a BREAKING note naming both keys, and @object-ui/app-shell patch. New pin AppHeader.dashboardReportCrumb-12273.test.tsx renders the real AppHeader under a real I18nProvider (en, zh) on both routes, plus page/object/record routes and a system-route CONTROL. Draft PR objectui#12279 is open, assignee zhuangjianguo, labelled needs:contract-review (read back), body 8109 bytes stored identical.",
    "zone2_measurements": [
    "1 CONFIRMED on 1fb1ced: the dashboard branch pushed { label: t('console.breadcrumb.dashboards'), href: baseHref } and the report branch pushed console.breadcrumb.reports the same way.",
    "2 CONFIRMED, re-measured over the whole tree with git grep -n -F on 1fb1ced: console.breadcrumb.dashboards 1 file (AppHeader.tsx); console.breadcrumb.reports AppHeader.tsx plus 2 lines of packages/i18n/CHANGELOG.md (release history of the 报表 ruling, not a reader; published CHANGELOG not edited); control console.breadcrumb.marketplace 8 files, 2 of them non-CHANGELOG (AppHeader.tsx, AppHeader.marketplaceBreadcrumb-10900.test.tsx). No dynamic console.breadcrumb head. Sibling objectstack checkout at df7a1379: 0 hits for both keys and also 0 for console.breadcrumb.marketplace/system, so that tree reads no console.breadcrumb key and the control cannot ring there; a host outside these repos stays unmeasured, as for the Pages retirement. No reader outside packages//src: plan unchanged.",
    "3 DONE: both routes rendered in the pin (the report trail is rendered for the first time)."
    ],
    "tests": "All at 12863df (the only commit; the tree was clean for every run). (1) Build closure: os-verify-lock -c 'pnpm exec turbo run build --filter=@object-ui/app-shell^... --concurrency=2' -- 'Tasks: 28 successful, 28 total', VERDICT command-exit 0. (2) New pin alone: 'Test Files 1 passed (1) / Tests 9 passed (9)'. (3) pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/layout/ packages/i18n/ -- 'Test Files 148 passed (148) / Tests 1790 passed | 13 skipped (1803)', VERDICT command-exit 0. (4) The 15 test files outside layout/ that name AppHeader (app-shell + apps/console) -- 'Test Files 15 passed (15) / Tests 118 passed (118)'. (5) pnpm --filter @object-ui/app-shell --filter @object-ui/i18n type-check -- 'packages/i18n type-check: Done', 'packages/app-shell type-check: Done', VERDICT command-exit 0; tsc -p tsconfig.test.json --listFilesOnly in app-shell lists the new test (1 hit; positive control the 12198 pin, 1 hit). ABLATION via objectstack scripts/ablation-replace.mjs wrap mode (relative import of ../AppHeader resolves src, no build needed): leg A planted the dashboards push back -- anchor 1 to 0, blob 2fc695ce6437 to f8be9f5247ea, 'Tests 2 failed | 7 passed (9)', both dashboard cases received ['console.breadcrumb.dashboards', 'Ops Board']; leg B planted the reports push -- 'Tests 2 failed | 7 passed (9)', received ['console.breadcrumb.reports', 'Sales Summary']; each restore: blob after restore == blob at HEAD 2fc695ce6437, git diff HEAD empty. The first leg-A attempt was a refused no-op (its replacement contained the anchor, count 1 to 1, the tool exited 1 and restored before any test ran); re-anchored and re-run as above.",
    "gates": [
    {
    "gate": "build closure (turbo, app-shell^...)",
    "exit": 0,
    "verdict": "28 successful, 28 total"
    },
    {
    "gate": "vitest packages/app-shell/src/layout/ packages/i18n/",
    "exit": 0,
    "verdict": "148 files passed, 1790 passed, 13 skipped"
    },
    {
    "gate": "vitest AppHeader-naming tests outside layout/",
    "exit": 0,
    "verdict": "15 files passed, 118 tests"
    },
    {
    "gate": "type-check @object-ui/app-shell + @object-ui/i18n",
    "exit": 0,
    "verdict": "both Done"
    },
    {
    "gate": "eslint touched files (narrowed, proven)",
    "exit": 0,
    "verdict": "12 files, 0 errors, 0 ignored; 22 no-explicit-any warnings in AppHeader.tsx, 22 at base; new test 0. Population: each package lint script is eslint . under root eslint.config.js, and the 12 touched source files all came back as results. Invariance: no parserOptions.project/projectService in eslint.config.js, no eslint-rules/ rule reads another file, so untouched files cannot change verdict."
    },
    {
    "gate": "pnpm check:i18n-keys",
    "exit": 0
    },
    {
    "gate": "pnpm check:i18n-drift",
    "exit": 0,
    "verdict": "0 en value(s) changed (0 key(s) added, 2 removed)"
    },
    {
    "gate": "pnpm check:i18n-dead-keys",
    "exit": 0,
    "verdict": "report-only"
    },
    {
    "gate": "pnpm check:i18n-designer-parity",
    "exit": 0
    },
    {
    "gate": "pnpm check:control-bytes",
    "exit": 0,
    "verdict": "OK (scanned 8559 tracked text files)"
    },
    {
    "gate": "pnpm check:new-line-citations",
    "exit": 0,
    "verdict": "0 new citation(s)"
    },
    {
    "gate": "node scripts/check-changeset-presence.mjs",
    "exit": 0,
    "verdict": "12 source files of 2 released packages, 1 changeset"
    },
    {
    "gate": "node scripts/check-changeset-no-major.mjs",
    "exit": 0
    },
    {
    "gate": "node scripts/check-changeset-fixed.mjs",
    "exit": 0
    },
    {
    "gate": "pnpm check:changeset-claims",
    "exit": 0
    },
    {
    "gate": "node scripts/check-changeset-overwrite.mjs",
    "exit": 0
    },
    {
    "gate": "pnpm check:pending-changeset-literals",
    "exit": 0
    },
    {
    "gate": "pnpm check:vi-mock-specifiers",
    "exit": 0
    },
    {
    "gate": "pnpm check:vi-mock-override-shape",
    "exit": 0
    },
    {
    "gate": "pnpm check:vi-mock-inherit",
    "exit": 0
    },
    {
    "gate": "pnpm check:test-path-roots",
    "exit": 0
    },
    {
    "gate": "node scripts/check-type-check-coverage.mjs",
    "exit": 0
    },
    {
    "gate": "pnpm check:unreferenced-sources",
    "exit": 0
    },
    {
    "gate": "node scripts/check-eager-locale-catalogues.mjs",
    "exit": 2,
    "verdict": "NOT MEASURED: eager-locale-catalogues, reason: PREREQUISITE NOT MET (needs a built apps/console bundle); left to CI. The diff only shrinks the packs."
    }
    ],
    "gates_note": "Derived by hand from objectui package.json and .github/workflows at 1fb1ced (objectui has no dispatch-gates.mjs); exit codes captured before any pipe (cmd to LOG; EXIT=$?). origin/main moved to 48fb558 (objectui#12277, ci type-check) after the branch point; it touches none of these paths and was not merged in.",
    "files_changed": [
    ".changeset/12273-dashboard-report-crumb.md",
    "packages/app-shell/src/layout/AppHeader.tsx",
    "packages/app-shell/src/layout/tests/AppHeader.dashboardReportCrumb-12273.test.tsx",
    "packages/i18n/src/locales/ar.ts",
    "packages/i18n/src/locales/de.ts",
    "packages/i18n/src/locales/en.ts",
    "packages/i18n/src/locales/es.ts",
    "packages/i18n/src/locales/fr.ts",
    "packages/i18n/src/locales/ja.ts",
    "packages/i18n/src/locales/ko.ts",
    "packages/i18n/src/locales/pt.ts",
    "packages/i18n/src/locales/ru.ts",
    "packages/i18n/src/locales/zh.ts"
    ],
    "line_budget": "n/a: no skills/
    and no line-budgeted ledger touched. Diff 13 files, +251/-34 (git diff --shortstat 1fb1ced 12863df).",
    "deviations": [
    "Zone 3 asked for 'a retired-key pin in the shape objectui#12247 used'. PR objectui#12247 added no pack-side retirement pin; its crumb pin is that shape (a re-planted crumb renders the retired key string), and this PR follows it. The harness is AppHeader.systemBreadcrumbs-10969's (real I18nProvider over the published packs, en and zh), not 12198's identity-t one. Both make a planted crumb read as its key string, as the ablation shows. No i18n pack-absence pin was added; the PR's Acceptance notes say so.",
    "The first ablation attempt (leg A) was a no-op that ablation-replace refused before any test ran. It is reported in the tests field and the PR body, not silently re-run.",
    "Commit trailers: AGENTS.md's model-free pair (Claude-Session + Co-authored-by: Claude), over the harness reminder's model-named Co-Authored-By, per the harness's own precedence sentence."
    ],
    "mcp_calls": "0",
    "api_writes": "3 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]: (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft forced) + its assignees leg POST /repos//issues/12279/assignees; (2) label-write = POST /repos//issues/12279/labels (needs:contract-review, read back MATCHES); (3) this os-dev-report comment = POST /repos//issues/12273/comments. Plus 2 git pushes (empty branch probe, then 12863df), which are not REST writes.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: 承接者:无 · noted in PR Acceptance notes, not filed. Observation only: check:i18n-dead-keys is report-only and in no workflow, so a pack key re-added with no reader would go unflagged by CI. That holds equally for console.breadcrumb.pages (PR objectui#12247). A re-added reader goes red in the new pin, and in check:i18n-keys while the key is absent."
    ]
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat ACCEPT: objectui PR #12279 at 12863df · domain:ui seat 1 · session_01CsyMRsFJBKNEMa4oPY1b5z · 2026-10-12T23:22Z

    Verdict: ACCEPT. Reviewed on GitHub against the claim 6134224892 and triage 6133338003, not against the report. It is gated on the at-tier contract review the narrowing owes, which runs once CI on this head has converged.

    PR form. Draft, base main, assignee zhuangjianguo. Line 1 is Fixes #12273 and line 2 is Clause-②: no (narrowing); a scan of the whole body found no other closing verb next to a card number. needs:contract-review is hung.

    Scope. 13 files, +251 / −34, all inside the claimed surface. check-governed-merges --pr reads NOT governed, 285 lines. Nothing is under content/docs/releases/.

    The diff, read.

    • AppHeader.tsx drops exactly the two extraSegments.push calls (console.breadcrumb.dashboards, console.breadcrumb.reports) and adds a comment citing the ruling. Nothing else in the file moves.
    • The ten packs drop both keys. In zh.ts the removal also takes the objectui#6166 terminology note (报表, not 报告) that sat on the retired key.
      • That ruling's record stays on objectui#6166.
      • The pack's remaining report keys (navReport, navTypeReport, the command palette's reports, typeReports, badgeReport, the nested report) all read 报表, so nothing is left inconsistent for the note to defend. Accepted as is.

    The changeset, sentence by sentence.

    • @object-ui/i18n minor with a BREAKING note naming both retired keys, and @object-ui/app-shell patch, with no major.
    • "the trail now goes from the app pill straight to the dashboard or report": the diff and the new pin.
    • "System and object routes draw their trails as before": the pin's CONTROL cases.
    • "each had one reader": the dev re-measured over the whole tree. Its only other hits are two release-history lines in packages/i18n/CHANGELOG.md, not readers, and the published CHANGELOG is rightly not edited.

    Evidence, as reported.

    • The new pin renders both routes through a real I18nProvider (en, zh); the report trail is rendered for the first time.
    • Two ablation legs, one planting each push back, turn the pin 2 red each, restored blob-equal to HEAD.

    Out of scope. That check:i18n-dead-keys is report-only is an Acceptance note with no carrier, an observation and not a filing-gate class.

    Next (the seat's). CI on 12863df is converging. Once it is green, an isolated at-tier contract review renders its record on this head. On PASS the seat strips needs:contract-review and runs pr_ready + automerge_enable.

    Implemented-by: claude/issue-12273-dashboard-report-crumb (mode:subagent dev of this seat)
    Reviewed-by: session_01CsyMRsFJBKNEMa4oPY1b5z


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: objectui PR #12279 → main 9f282ef · domain:ui seat 1 · session_01CsyMRsFJBKNEMa4oPY1b5z · 2026-10-12T23:55Z

    • Merged through the merge queue; this card closed completed by the PR's Fixes #12273.
    • Landed by content, not by sha: all 13 of the PR's files on main 9f282ef are blob-identical to the head the contract review judged, 12863df (record 6134710052, PASS).
    • pm:dispatched removed (read back); domain:ui, area:records, type and priority stay.
    • The changeset (@object-ui/i18n minor with a BREAKING note naming the two retired keys; @object-ui/app-shell patch) rides the next objectui release.

    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

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions