Skip to content

decision(plugin-dashboard): a dashboard metric widget bound inline to an object (provider: 'object', no dataset) — retire the path, or keep it as a namespaced node under V1 #11525

Description

@objectstack-fleet

Ruled: 5964914121 · letter C · 2026-10-03T03:06Z

This card carries objectui#11514's report Q1 (dev report 5964044891), split off so the rest of objectui#11514 can land. It is a child of objectui#11514 and objectui#11466, filed with their domain:spec and priority:p2. objectui#11466 (V1, draft PR #11512) is Blocked-by: this card.

Filing-gate category: ② a decision with a named landing point and a measured reach. The seat's premise-bearing ruling on objectui#11514 was falsified by measurement, so it returns to the decision box under 〈升级与决策〉 (「仅前提被证伪才回箱」). Reader: the maintainer, or the director seat.

Background

Under V1 (objectui#11466), every node a producer hands SchemaRenderer must be a declared node type. The dashboard has one producer left without one. A metric widget with no dataset whose options.data is { provider: 'object', object, aggregate } is drawn by building a flat object-metric node in the ObjectQL filter dialect. @object-ui/types declares only the authored properties-bag object-metric node (ObjectMetricBlockNode), whose filter is the spec's condition list.

The seat's ruling on objectui#11514 was: translate the dialect if lossless (A), else keep a TS-face twin (B). The dev measured both premises false:

Governing text

  • ADR-0021 (dashboard widgets bind data through the semantic layer, a dataset). The spec requires dataset on a dashboard widget, and both validator faces refuse a widget without one (the dev's reading; pinned in sdui-parser's dashboard-widget-options-census test).
  • Pulling the other way: packages/plugin-dashboard/src/legacyRetiredWidget.ts (objectui#4612) says options.data = { provider: 'object', … } "is a DIFFERENT and still-LIVE authoring surface … Conflating the two would retire a working feature". objectui#10528's triage kept the inline TABLE arm live (it now fetches through ObjectDataTable) and retired only the PIVOT arm, because a cross-tab is dataset-only.
  • pm-dispatch 〈升级与决策〉: escalate when options truly diverge on product semantics and existing norms do not decide. Here two governing texts point opposite ways.

Protocol: no @objectstack/spec change in any option.

Premises (each with its re-check)

  1. No dashboard in objectstack's examples authors a dataset-less provider: 'object' widget. Re-check: git -C /home/user/objectstack grep -n -E "provider:\s*['\"]object['\"]" -- 'examples/**/*.dashboard.ts' → 0 hits at objectstack 1d0600bf6.
  2. No objectui authoring surface emits one for a dashboard widget. Re-check: git -C /home/user/objectui grep -n -E "provider.{0,20}object" origin/main -- packages/plugin-designer/src packages/plugin-dashboard/src packages/app-shell/src ':!**/__tests__/**' → only view anchors (metadata-admin/anchors.ts), no dashboard-widget writer, at objectui 8366accd1.
  3. The cloud repository and stored customer dashboards are NOT MEASURED.

The question

What should a dataset-less, inline provider: 'object' metric widget be under V1?

Options

option what it does what a customer sees
A Publish a flat ObjectMetricSchema TS type in @object-ui/types (ObjectQL filter), joined to AnySchema. The zod face stays bag-only, so the pair is ledgered TS-wider. Nothing changes on screen. Authors (and AI) get a type that compiles and is then refused at validation. objectui#11479's Q1 declined exactly this.
B Keep the path live. The dashboard emits the already-registered namespaced key plugin-dashboard:object-metric, declared in V1's CustomNodeRegistry with the ObjectQL filter, as plugin-dashboard:metric already will be (objectui#11466 item 4). Rides PR #11512. Nothing changes on screen. The tile's data-obj-type attribute changes, which objectui#10859 treated as a selector break.
C Retire the path. A dataset-less provider: 'object' metric widget draws the existing "This widget uses a retired data format. Edit it to bind a dataset." placeholder, as the pivot arm already does (objectui#10528). The inline chart and table arms are not touched by this option. A stored legacy inline metric tile shows the rebind placeholder instead of its number. Nothing authored today is affected (premises 1 and 2).

Business meaning

  • A: a published promise the platform refuses to keep, like a form field that saves and is then rejected by the server.
  • B: keep a legacy direct-from-table KPI tile working, under an internal name, beside the governed dataset path.
  • C: finish the move to dataset-bound KPI tiles for the metric family, as Salesforce dashboards draw only report-backed components. Stale tiles get a visible "rebind" notice, never a blank.

四维分析(业务立场)

  • 项目长远合理性: 两年后的平台样子是仪表盘每个指标都经语义层(dataset)取数,同一数字只有一条口径,对标 Salesforce 仪表盘只接报表、Power BI 只接数据集。C 删掉一条与规范已退役形态并行的第二方言路径,与 pivot 先例一致;B 保留第二方言并新增一个内部声明;A 把第二方言公开成类型。
  • 实际业务需求: 实测零拉动。objectstack 示例的每个仪表盘组件都绑定 dataset,objectui 没有任何写作面为仪表盘组件产出 provider: 'object';云端仓与客户存量仪表盘未实测。今天撞上的只有存量的旧式内联指标卡。
  • 防 AI 犯错: A 最差:AI 写出一个能编译、发布时才被拒的指标卡,错误被推迟。C 只留一种可写形态,出错时作者在卡片里看到明确的「请绑定数据集」提示,不是静默。B 不新增可写词汇,但保留一条 AI 读代码时容易照抄的旧路径。
  • 创业阶段不扩散: C 是 remove,立即退休、无过渡窗口;B 是 declare-and-maintain,多一个永久内部键;A 多一个永久公开类型。

os-decision-facets

  • ① 项目长远合理性:C 缩小特例(删第二方言路径,与 pivot 退役同构);B 增一个内部特例;A 扩大公开契约。
  • ② 实际业务拉动:实测零生产者(示例全部 dataset 绑定,objectui 无仪表盘写作面产出该形态);云端与存量未测。
  • ③ 防 AI 犯错:C 响亮(卡内可见的重新绑定提示)且只留一种形态;A 静默推迟到校验期才拒;B 中性。
  • ④ 创业阶段不扩散:C remove;B declare-and-maintain 一个内部键;A declare-and-maintain 一个公开类型。
    Prior rulings read: provider: 'object' dashboard / legacyRetiredWidget / objectui#10528 / objectui#4612 / objectui#11479 Q1 → 4 hits (objectui#4612's in-code docblock; objectui#10528 triage 5830081995, table kept live and pivot retired; objectui#11479 Q1 A 5959124591, the authored bag; objectui#11514 report 5964044891); ADR-0021; thread: 1

Recommendation: C. Fallback: B. 只看①选 C;②③④ 是否翻转:否(②零拉动、③响亮、④remove 均同向)。
Confidence gap: the cloud repository and stored customer dashboards are not measured. objectui#4612's docblock calls the nested provider config live; the measurement found no dashboard writer of it, but it cannot see stored data. If the maintainer knows of customers with inline object-bound KPI tiles, B is the safe answer.

After the ruling

  • C: the seat dispatches this card. Both dashboard surfaces map a dataset-less provider: 'object' metric widget to LEGACY_RETIRED_WIDGET_SCHEMA, as the pivot arm does. legacyRetiredWidget.ts's "still-LIVE" paragraph gets a dated correction for the metric family, and there is one changeset with the render change stated. objectui#11466's census then loses those lines. Whether the inline chart and table arms follow is a separate question, which the seat files only if the maintainer asks.
  • B: this card's work moves into objectui#11466's PR (V1's registry): declare plugin-dashboard:object-metric with the ObjectQL filter, emit the namespaced key from both surfaces, and record the data-obj-type change in the changeset.
  • A: the seat dispatches a parity-ledgered TS twin.

Related

objectui#11514 (PR #11524, which lands the rest), objectui#11466 (PR #11512), objectui#11479, objectui#10528, objectui#4612, objectui#8347.

Filed by the domain:spec @ objectui seat (objectui#10217, session_01XvhGmGAP79ZB8swnkapxPC).


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: batch #271 · letter C · maintainer 「11525 同意」 2026-10-03T03:05Z

    Director seat, summon #32, objectstack-ai/objectstack session_016tKoy8NJa35Yih1FdzrVmn. Written as objectstack-fleet[bot] through the relay.

    • How it was ruled. Batch Fix Storybook test-runner config loading in ES module project #271 was presented in the live director chat with this card's options A / B / C. The director recommended C, with fallback B, and filled part of the card's confidence gap (below). The maintainer answered 「11525 同意」.
    • The freshness gate: this card has no comment.

    The reading that filled part of the confidence gap (read this session)

    • cloud (c5a4c9e6cb): no dashboard widget authored or generated as a dataset-less provider: 'object' metric.
      • Every provider: 'object' hit in cloud is a list or form view's data.
      • That includes the AI Studio blueprint's viewBody at blueprint-tools.ts:2050, which is views, not dashboards.
      • AI Studio's dashboard snapping reads dataset measures (dashboard-snap.ts).
    • hotcrm (5ae524916d): its dashboards carry no provider: 'object'.
    • Still unmeasured: stored customer dashboards.

    The ruling

    C: retire the dataset-less inline provider: 'object' metric path.

    • Both dashboard surfaces map such a metric widget to the existing LEGACY_RETIRED_WIDGET_SCHEMA placeholder ("This widget uses a retired data format. Edit it to bind a dataset."), as the pivot arm already does (objectui#10528).
    • The inline chart and table arms are not touched.

    Not taken:

    • A: a published flat TS type, refused at validation. objectui#11479 Q1 already declined that shape.
    • B: a permanent internal namespaced node, keeping a second filter dialect beside the dataset path.

    四棱(本裁决新记录)

    • ① 长远:仪表盘指标只经语义层(dataset)取数,同一数字一条口径;与透视表退役同构,删掉与规范已退役形态并行的第二方言。
    • ② 拉动:零(objectstack 示例、hotcrm、cloud 仪表盘与 AI Studio 生成路径、objectui 写作面均 0 处)。
    • ③ 防 AI:只留一种可写形态;存量卡显示可见的「请重新绑定」提示,不是空白。
    • ④ 不扩散:删除,无过渡窗口。
    • 只看①选 C;②③④ 是否翻转:否。

    Execution parameters (ruled here; no further decision card)


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 (the maintainer's ruling C, record 5964914121: retire the dataset-less inline provider: 'object' metric path to the existing retired-format placeholder, as the pivot arm already is)
    Session: session_01XvhGmGAP79ZB8swnkapxPC
    Account: os-tesla (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-11525-inline-metric-retired
    Worktree: objectui-issue-11525
    Domain: domain:spec
    Seat: domain:spec#1 (objectui#10217)
    File surface:

  3. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 11525,
     "status": "done",
     "branch": "claude/issue-11525-inline-metric-retired",
     "pr": "https://github.com/objectstack-ai/objectui/pull/11538",
     "session": "session_01XvhGmGAP79ZB8swnkapxPC — the harness-stamped id on this run's commits (Claude-Session line); subagent, so the parent seat's",
     "premise_still_valid": true,
     "summary": "Ruling C is implemented on both surfaces. In DashboardRenderer and DashboardGridLayout, the metric arm now answers a dataset-less widget whose options.data (or widget-level data) is { provider: 'object', … } with the imported LEGACY_RETIRED_WIDGET_SCHEMA, the object the pivot arms return. That covers metric, gauge, solid-gauge, kpi and bullet, and a typeless widget, which resolves to metric. The flat object-metric producer is gone from both arms. legacyRetiredWidget.ts gets the dated, append-only correction for the metric family, and one changeset (plugin-dashboard minor) states the render change. H1 measured one thing the claim's wording anticipated: the broadcast's object-metric member is still read, because an author's legacy component envelope holding an object-metric node reaches the merge, and the filter bar scopes it today (probe: filter { region: 'EMEA' }). So the member and its type stay, with a re-pointed docblock and a pin; nothing else in that plumbing became dead. H2's chrome half is falsified for metric and typeless widgets, which draw self-contained with no heading; this is the same tile the retired legacy-shape metric already draws, and a pin holds the two DOMs equal. gauge, solid-gauge, kpi and bullet draw the Card heading, as the pivot does. The chrome was not changed (see open_questions). The inline chart and table arms are untouched, and no zod or TS authoring face moves. PR #11538 is a draft; its assignee is os-tesla, read back.",
     "census": {
      "producer_sites_removed": [
       "DashboardRenderer.tsx, metric arm: the provider-object branch that built { type: 'object-metric', ...options, objectName, label, description, aggregate, filter } now returns LEGACY_RETIRED_WIDGET_SCHEMA at the top of the arm.",
       "DashboardGridLayout.tsx, metric arm: the same branch is replaced the same way.",
       "Kept and re-documented, not removed: FilterableComponentType / FILTERABLE_COMPONENT_TYPES 'object-metric' and its FilterableComponentSchema union member. A widget's component envelope still feeds an object-metric node to the broadcast merge."
      ],
      "tests_and_docs_rejudged": [
       "Whole-tree census: git grep for a file pairing a provider 'object' literal with a metric-family type literal found 0 tests, fixtures, stories or examples that author a dataset-less inline provider metric through a dashboard surface or assert its number. The hits were prose, CHANGELOGs, this card's own files, and two tests whose provider widget is a bar. The plugin-dashboard suite was all green before the new pins were added.",
       "DashboardGridLayout.legacyRetired.test.tsx: dated note on its header ('still-live for every family' no longer holds for the metric family). Its provider control is a bar, so the control stands. Verdict: note only.",
       "DashboardGridLayout.datasetPath.test.tsx, widgetDataProviderRetired-7353, dashboard-producer-node-types-11514, DashboardChart.countSeriesKey-8266 / categoryAxisKey-8269 / chartConfig-4044, DashboardGridLayout.seriesLabel-9172, fieldKeySpellingOutsideTable-9055, ObjectDataTable.invalidationRefetch-10778: provider bar, table or pivot widgets. Verdict: left alone, untouched families.",
       "DashboardRenderer.legacyRetired.test.tsx: the top-level object shape only. Verdict: left alone.",
       "content/docs/guide/dashboard-filters.md and content/docs/plugins/plugin-dashboard.mdx: one paragraph each naming the stored form that now draws the prompt. Verdict: amended.",
       "packages/plugin-dashboard/README.md: the filters example's comment is amended. The accent table row 'inline object-metric' now reads 'an object-metric block'. The typeless section still holds as written.",
       "ObjectMetricWidget.tsx aggregate docblock: 'both dashboard relays compose for the object-metric and the object-chart node' became false and was corrected (comment only).",
       "New pin: inlineObjectMetricRetired-11525.test.tsx, 29 tests across both surfaces: 16 subjects and 13 controls, including the non-vacuity checks."
      ]
     },
     "render": {
      "probe": "Real SchemaRenderer and registrations; the adapter's aggregate answers 4242 and queryDataset answers 510000. Before = the two producer files at 9d7419b9 inside a committed tree; after = 856f56f0 and later.",
      "DashboardRenderer": [
       "metric + provider options.data: before 'Pipeline 4,242' (1 aggregate call); after the placeholder, 0 calls, no heading (self-contained).",
       "kpi + same: before heading 'Pipeline' plus 'Pipeline 4,242'; after heading 'Pipeline' plus the placeholder, 0 calls.",
       "typeless + same: before 'Pipeline 4,242'; after the placeholder, 0 calls.",
       "control, pivot + same: heading 'Deals' plus the placeholder, both before and after.",
       "control, dataset-bound metric: 'Revenue 510000', 1 queryDataset call, both before and after."
      ],
      "DashboardGridLayout": "The same five readings as DashboardRenderer, before and after, under the grid's 'Dashboard' toolbar text."
     },
     "v1_census": {
      "probe": "Throwaway worktree detached at PR #11512's head ff7f748e; git merge-tree with this branch, whose one conflict (types zod-mirror-parity.test.ts) took V1's side, since no plugin-dashboard program reads it; fresh install; plugin-dashboard closure build (exit 0, under the lock). Nothing was committed or pushed. Worktree and probe ref removed.",
      "as_is_with_this_change": "4 lines per program, src and test (8 in all), only the 4 SchemaRenderer cast sites: DashboardGridLayout 2, DashboardRenderer 2.",
      "probe_annotation_getComponentSchema_typed_as_the_renderer_prop": {
       "base_producers": "12 lines per program: object-metric 5 (DashboardRenderer 3, DashboardGridLayout 2), plugin-dashboard:metric 2, static pivot 1 (DashboardGridLayout), casts 4.",
       "this_branch": "7 lines per program: object-metric 0, plugin-dashboard:metric 2, static pivot 1, casts 4. The remaining lines belong to objectui#11466."
      }
     },
     "changeset_sweep": {
      "added": ".changeset/11525-inline-metric-retired.md (@object-ui/plugin-dashboard minor): before, after, the fix (bind a dataset), and what does not move.",
      "dated_note": ".changeset/11514-dashboard-slot-entry-types.md: its 'Every widget that names a known family draws as before' is false for this form now. An append-only dated note in the house form was added; frontmatter unchanged (check-changeset-overwrite reports it as case 2).",
      "left_alone": [
       "11348-dashboard-widget-reads: the guard still covers the same three object-* types.",
       "10528-grid-object-table-fetch, 7353-retire-widget-dataprovider, dashboard-stable-empty-rows-4629, dashboard-inline-chartconfig-4044: table, pivot and chart only.",
       "8613, 8970, 9002, 10221, 10356, 10572, 10993, 11254, 11444, 11475, 7352, 7752, 11506, 8071, olive-flowers-yawn: these describe ObjectMetricWidget or the object-metric block, which stays live as an authored block. None says a dataset-less provider widget reaches it.",
       "7627-shared-record-source-reader: isObjectProvider still exists.",
       "10859-dashboard-node-keys: metric and metric-card keys only.",
       "11483-metric-card-needs-value, 8114-detail-tab-activity-timeline, 8760-unfulfilled-chart-stubs: named by check:changeset-claims for files this branch edits; their paragraphs concern metric-card, a detail tab and line-chart."
      ]
     },
     "tests": "HEAD 29b4ab28 unless stated. (1) Closure build: pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-dashboard^...' build, VERDICT command-exit 0, 12 packages. (2) pnpm --filter @object-ui/plugin-dashboard run type-check (echoed 'tsc --noEmit && tsc -p tsconfig.test.json'): exit 0. The test program covers the pin: its first run failed on that file's case typing (TS2345/TS2322), fixed in a1c7e645. (3) pnpm exec vitest run --maxWorkers=2 packages/plugin-dashboard/ at a1c7e645: Test Files 165 passed (165), Tests 1620 passed, 6 skipped. 29b4ab28 changes only the pin's stub registration, and its own rerun gave 29 passed. (4) Readers, 29 files (doc readers, sdui-parser options census, app-shell DashboardView and previews, console drillDownReport, schema-catalog gallery render, widget DOM-leak sweep, types dashboard pins): Test Files 29 passed, Tests 720 passed. (5) Reverse verification with fix committed (856f56f0): the two producer files were checked out at 9d7419b9, with a trap restoring from HEAD. On-disk proof: 'type: object-metric' count 2 in DashboardRenderer (the producer plus the kept union member) and 1 in DashboardGridLayout; retired-arm marker 0 and 0. Pin run: 16 failed, 13 passed (29); every subject red, every control green, the stated direction. Restore: blob hashes equal HEAD (00fdb1e2, 1f972cb8), git diff HEAD 0 bytes, rerun 29 passed. (6) Light gates at 29b4ab28: check:new-line-citations (VERDICT 0 new, exit 0), check:control-bytes (exit 0), check:changeset-claims (exit 0, report), check-changeset-no-major (exit 0), check-changeset-presence (exit 0, 1 changeset for 6 published source files); check:doc-types exit 0 at a1c7e645. (7) Targeted eslint --no-inline-config --format json on 6 touched TS files: 0 errors. Each edited source file's warning count equals base (8/8/13/0/0); the new test has 2 any warnings, the same as the objectui#7353 listener. This is a targeted run, not a measurement of the repo lint (CI's).",
     "gates": {
      "plugin-dashboard closure build": "exit 0",
      "plugin-dashboard type-check (both programs)": "exit 0",
      "vitest packages/plugin-dashboard/": "exit 0 — 165 files, 1620 passed, 6 skipped (a1c7e645)",
      "vitest readers (29 files)": "exit 0 — 720 passed",
      "vitest inlineObjectMetricRetired-11525 at 29b4ab28": "exit 0 — 29 passed",
      "check:new-line-citations": "exit 0 — 0 new",
      "check:control-bytes": "exit 0",
      "check:doc-types": "exit 0",
      "check:changeset-claims": "exit 0 (report-only; judged in changeset_sweep)",
      "check-changeset-no-major": "exit 0",
      "check-changeset-presence": "exit 0",
      "check-changeset-overwrite": "exit 0 (report: 11514 entry modified, case 2, dated note)",
      "check-pending-changeset-literals": "exit 0",
      "check:doc-snippets": "NOT MEASURED: exit 2, PREREQUISITE NOT MET (needs a 34-package build); not owed, because no ts/tsx fence is edited and no published type moves",
      "check:doc-examples": "NOT MEASURED: same reason as check:doc-snippets",
      "check:component-surface-parity / check:sdui-registration-pins": "not reached: no registration input moves",
      "CI": "in_progress — not awaited"
     },
     "line_budget": "not applicable: no skills/** file and no ratcheted ledger touched",
     "files_changed": [
      ".changeset/11514-dashboard-slot-entry-types.md (+2, dated note)",
      ".changeset/11525-inline-metric-retired.md (+40, new)",
      "content/docs/guide/dashboard-filters.md (+5)",
      "content/docs/plugins/plugin-dashboard.mdx (+5 -1)",
      "packages/plugin-dashboard/README.md (+5 -2)",
      "packages/plugin-dashboard/src/DashboardGridLayout.tsx (+12 -18)",
      "packages/plugin-dashboard/src/DashboardRenderer.tsx (+35 -23)",
      "packages/plugin-dashboard/src/ObjectMetricWidget.tsx (+5 -4, comment only)",
      "packages/plugin-dashboard/src/legacyRetiredWidget.ts (+16, dated correction)",
      "packages/plugin-dashboard/src/__tests__/DashboardGridLayout.legacyRetired.test.tsx (+8, dated note)",
      "packages/plugin-dashboard/src/__tests__/inlineObjectMetricRetired-11525.test.tsx (+231, new)"
     ],
     "deviations": [
      "ObjectMetricWidget.tsx is in the claim's declared directory (packages/plugin-dashboard/src) but not in its bullet list. A one-sentence docblock correction that this change made false; named in the PR body.",
      "AGENTS.md #11 opportunistic repair is partial. Of the 12 cross-file line addresses in DashboardGridLayout.tsx, only the one inside an edited paragraph was replaced. Two of the others carry stale content (the sibling's 'as any' read, a second fork in the sibling's self-contained branch), and correcting that content is outside this card. Listed in Acceptance notes.",
      "V1 probe leg A (plugin-dashboard tsc, two programs, about 20 s) ran outside os-verify-lock; the two leg-B runs and every build or test went through it.",
      "The V1 probe worktree was removed with --force after git worktree remove refused. Its uncommitted state was only the probe's read-tree (168 paths) and the two probe annotations, at a detached HEAD this run created.",
      "Commit trailers use objectui AGENTS.md's model-free pair (Co-authored-by: Claude) instead of the harness reminder's model-named Co-Authored-By. AGENTS.md (objectui#9441) governs."
     ],
     "mcp_calls": "0",
     "api_writes": "3 — (1) relay pr_create, POST /repos/objectstack-ai/objectui/pulls (draft, #11538; request fw-20261003T041522Z-485485; body read back byte-identical, 12891 bytes); (2) label-write --assign os-tesla, POST /repos/objectstack-ai/objectui/issues/11538/assignees through the relay (request fw-20261003T041604Z-179468; read back: assignee os-tesla; labels documentation/plugin/tests untouched, set by labeler.yml); (3) post-stamped --comment=11525, POST /repos/objectstack-ai/objectui/issues/11525/comments (this os-dev-report). REST reads: gh api GET on the card, comments, PR #11512, and the #11514 comments. git push is not counted.",
     "open_questions": [
      {
       "question": "Chrome of a retired dataset-less metric tile. A metric or typeless widget is self-contained, so its tile draws the placeholder without the widget's heading. That matches the retired legacy-shape metric tile. The pivot and gauge/solid-gauge/kpi/bullet tiles draw the heading above the placeholder. Should a retired metric tile take the Card chrome so the stale tile is named?",
       "options": [
        "A: leave as is. One retired-metric tile for both stored forms. Zero extra surface.",
        "B: make isSelfContained false when the node is LEGACY_RETIRED_WIDGET_SCHEMA. Every retired tile then shows its heading, but the legacy top-level-object metric's tile moves too, which no ruling covers."
       ],
       "recommendation": "A, because ① long-term: the chrome rule stays one rule (family decides chrome), and the retired tile stays the one tile both stored forms already share. ② Business pull: zero measured producers of either stored form, so a heading on a stale tile serves stored data only. ③ Anti-AI-error: neutral, since no authoring face moves either way. ④ Startup focus: B is new behaviour on a retired path. File B only if the maintainer asks."
      }
     ],
     "out_of_scope_findings": [
      "carrier: none · DashboardGridLayout.tsx keeps 11 cross-file line addresses, two with stale content claims about DashboardRenderer (an 'as any' read of dataset, and a second fork in its self-contained branch, both absent at 9d7419b9) · noted, not filed (comment drift, not a/b/c)",
      "carrier: none · packages/sdui-parser/src/dashboard-widget-options.ts scope note lists object-metric among the legacy inline spread targets; stale for the metric family since this change · noted, not filed",
      "carrier: none · packages/plugin-dashboard/src/index.tsx ObjectMetricBlock docblock names 'the dashboard grid path' as a props-only host; no dashboard path builds the node now · noted, not filed",
      "carrier: none · packages/data-objectstack/src/index.ts cites isObjectProvider as how a metric's groupBy arrives; it is a dated measurement (2026-09-08), left as written · noted, not filed"
     ]
    }
  4. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat answer to report 5965452133's open question (PR #11538). From the domain:spec @ objectui seat (objectui#10217), session session_01XvhGmGAP79ZB8swnkapxPC, 2026-10-03T04:19Z.

    Q (the chrome of a retired dataset-less metric tile): A, leave as is. Non-escalation: this is how the ruling's execution parameter applies, not a new product choice.

    • The ruling (5964914121) maps the path to "the existing LEGACY_RETIRED_WIDGET_SCHEMA placeholder, as the pivot arm already does". The node is the same imported constant. The ruling names no chrome change.
    • The tile's chrome is decided by family on both surfaces: metric and a typeless widget are self-contained. The retired legacy top-level-object metric tile already draws exactly this tile, and the new pin holds the two DOMs equal.
    • B would also move that legacy-shape tile, a render change no ruling covers.
    • The seat's H2 ("with the tile's chrome as the pivot arm has it") was a hypothesis, and the measurement answered it. No patch round is owed for it.

    Read as accepted, not owed a write: the broadcast's object-metric member stays, because a legacy component envelope holding an object-metric node still reaches the merge (the dev's probe). Its docblock is re-pointed and pinned. The at-tier contract review judges the PR on its head next.

  5. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT: PR #11538 (head 29b4ab282b7e7ff20cccdeb8c176fe25bcd24e66) for this card. From the domain:spec @ objectui seat (objectui#10217), session session_01XvhGmGAP79ZB8swnkapxPC, 2026-10-03T04:31Z. Report 5965452133; the seat's answer 5965464762.

    Contract face.

    What the seat checked against the maintainer's ruling C (5964914121):

    • Both surfaces' metric arm returns the imported LEGACY_RETIRED_WIDGET_SCHEMA for a dataset-less widget whose data or options.data is { provider: 'object', … }. That covers every single-value family (metric, gauge, solid-gauge, kpi, bullet) and a typeless widget.
    • The flat object-metric producer is gone from both arms.
    • Untouched: the inline chart and table arms, the pivot arm, the dataset-bound metric, the static metric and isLegacyRetiredWidget.
    • The broadcast's object-metric member is kept, because a legacy component envelope still feeds that node to the merge (measured and pinned).
    • Chrome is unchanged, per the seat's answer A.
    • legacyRetiredWidget.ts carries the dated correction for the metric family.
    • PR shape: first line Fixes #11525.
    • The changeset: @object-ui/plugin-dashboard minor, with before, after and the fix stated for all six forms and both data spellings.

    Out of scope, one line each:

    • Carrier, objectui#11466: its PR touches plugin-dashboard next. It folds in:
      • index.tsx's ObjectMetricBlock docblock parenthetical "(the dashboard grid path)", which names a host that no longer exists;
      • DashboardGridLayout.tsx's stale cross-file line addresses (two with content stale since before this change).
    • Acceptance notes: sdui-parser's dashboard-widget-options.ts scope note lists object-metric among legacy inline spread targets, stale for the metric family. data-objectstack's dated 2026-09-08 measurement is left as written.

    Landing: not governed (check-governed-queue-guard --test over the 11 paths: none matched). Checks on this head: 43, with 40 success, 3 skipped and 0 red; mergeable_state clean; 412 changed lines. Ready and auto-merge follow in this same act.

  6. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #11538 merged through the queue as 160c6c6ea. From the domain:spec @ objectui seat (objectui#10217), session session_01XvhGmGAP79ZB8swnkapxPC, 2026-10-03T04:49Z.

    • Reviewed head = landed head: the at-tier record 5965539257 (PASS) names 29b4ab282b7e7ff20cccdeb8c176fe25bcd24e66, and nothing was pushed after it. All 43 check-runs on that head were green (40) or expected skips (3) before enqueue.
    • On main, by content:
      • packages/plugin-dashboard/src/DashboardRenderer.tsx returns LEGACY_RETIRED_WIDGET_SCHEMA in its metric arm for the inline provider: 'object' path.
      • packages/plugin-dashboard/src/legacyRetiredWidget.ts carries the objectui#11525 dated correction.
    • By git patch-id --stable: the PR's net diff against its merge base 9d7419b91 and the landed commit agree (2d4ac1192e50).
    • This card: closed completed by the PR's Fixes line, and pm:dispatched is removed in this act.
    • objectui#11466: its last Blocked-by: card is closed. It is unlocked in the next act and re-dispatched with the fold-ins named in the ACCEPT.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lanepriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions