Repository navigation
finding(app-shell): DashboardView's header comment cites DashboardSchema.title, a key the spec refuses BY NAME #7509
Description
Activity
- addeddomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seat
on Sep 3, 2026 os-project-manager commented
on Sep 3, 2026 CollaboratorAuthorMore actionsAuthorship note. Filed by the
domain:uidev seat (Claude Code, sessionsession_01EMrWaQw3XS5DxTHxp4yRyC) while working objectui#7014; PR objectui#7510 carries the sibling corrections.Recording it here because the attribution footer written into the issue body was stripped by the platform on this repo — measured on this very card, not assumed: the body reads back at 2981 bytes with the trailing rule and footer absent. This reproduces the behaviour #7014's own authorship note recorded on #7014 / #7021 / #7023, so it is still live as of 2026-09-03.
Generated by Claude Code
os-project-manager commented
on Sep 3, 2026 CollaboratorAuthorMore actions席内核验:通过。PR #7520 —— 普查结论零供应者,按围栏停在交付 1
domain:ui执行席,sessionsession_01EMrWaQw3XS5DxTHxp4yRyC。承重读数自测。⭐ 它订正了本卡正文的一个前提,而且订正是对的
本卡正文写:
the fallback chain (
titlethenlabelthenname) still works for a host that passes apreviewSchemacarryingtitle没有那个 host 通道。 实测
origin/main:DashboardView.tsx:38 export function DashboardView({ dataSource }: { dataSource?: any }) ← 唯一的 prop DashboardView.tsx:129 const previewSchema = useMemo(() => { ← 本地,不是传入 DashboardView.tsx:177 const headerSrc = (previewSchema as any) || dashboard; DashboardView.tsx:178 const resolvedTitle = resolveKeyedI18nLabel(headerSrc.title, t);previewSchema是这个 view 自己的useMemo(把dashboard剪掉 widget 的副本),所以headerSrc的两条路都源自dashboard。⇒headerSrc.title在任何情况下都是dashboard.title—— 存储sys_dashboard文档上的键,正是 spec 拒收的那个面。⇒ 「preview-only」是错的,实际是 legacy-document-only。这不削弱本卡,是锐化它:那个 arm 不是给 preview 用的兜底,它是遗留存储文档在这一处的唯一读点。
⭐ 它预先避开了一个本席今天事后才踩到的对照陷阱
它指出本卡的对照有假阳性风险:
the card's "control (no title) ACCEPT" only holds when
labelis present, sincelabelis required — a bare{ name, widgets }control fails onlabel, not ontitle⚠️ 这正是本席今天在核验 #7014 时真的踩到的形状:我的「干净 option」对照自己红了(too_small,因为我用了单字符值),我重跑到对照点亮才敢记结论。这位实现者是动手前就想到了同类陷阱并把控制量设计对。⇒ 记在这里,因为「对照必须为它声称的原因而通过」比「对照必须点亮」更严格一层,而后者才是本轮反复强调的那条。普查:零仓内供应者,每个零配点亮的对照
三条探针都是声明/AST 形状,不是裸词:JSON 结构走查(546 文件 / 9 个 dashboard 形状节点,6 命中)、TS-AST 对象字面量(4137 文件 / 78 个含
widgets数组的字面量,12 命中)、TS-AST 赋值表达式(4137 文件,12 命中但没有一个在 dashboard 文档上)。分诊后:6 个 JSON 全是SchemaRenderer消费的组件 schema(无name),够不到按name从useMetadata().dashboards取的DashboardView;12 个 TS 里 9 个是测试夹具、1 个是 objectui 自己的DashboardConfigSchema声明,剩两个一个是组件注册的defaultProps、一个在!dashboard分支里而该分支直接 early-return 从不持久化。真正写 dashboard 文档的作者面
metadata-admin/dashboard-schema.ts由 specDashboardSchema经z.toJSONSchema派生,结构上发不出title。⛔ 处置 2 不做,理由是实质的而不是「按指示停下」
单子要求普查为零就停,它停了 —— 但它给的理由比服从更好:本卡援引的两个同类先例 #5830 / #5852 退休的都是无人读的键,而这个
title有五处读点(DashboardView:178、DashboardRenderer:947、DashboardGridLayout:394、DashboardEditor:467、DashboardDesignPage:138)。本席再补一条它没说、但更决定性的:删掉
DashboardView这一处而留下其余四处,会造成同一份遗留文档在不同视图里显示不同标题 ——DashboardRenderer仍读title,DashboardView回落到label。⇒ 这一处不能单独删;要么五处同波处理,要么都不动。这就使它明确是设计裁定而非修复。处置
- PR docs(app-shell): DashboardView's header comment stops attributing
titleto the spec #7520 用Refs而非Fixes,正确。CI 16:22 起跑,全绿即剥 draft 放行。Clause-② no 复核确认(只改注释文字 + 空 frontmatter changeset)。 - PR 落地后本卡转
needs-user-decision,⛔ 不带pm:queue(卡片自身说不可派工而标签仍在招手,正是 finding(process): 5 of 6pm:queue+domain:uicards read this round were not dispatchable — 3 of them say so in their own body, and only reading the body reveals it #6853 点名的缺陷)。届时待裁的是:五处title读点是否同波退休,以及平台侧遗留sys_dashboard文档的存量需不需要先测。 - 本卡正文那句「preview-only」的措辞未改 —— 按本仓惯例更正归下一个认领者;在那之前本评论与 PR docs(app-shell): DashboardView's header comment stops attributing
titleto the spec #7520 的正文是权威读数。
Generated by Claude Code
- PR docs(app-shell): DashboardView's header comment stops attributing
os-project-manager commented
on Sep 3, 2026 CollaboratorAuthorMore actionsos-dev-report
{ "issue": 7509, "status": "needs_decision", "branch": "claude/issue-7509-dashboard-title-claim", "pr": "https://github.com/objectstack-ai/objectui/pull/7520", "premise_still_valid": true, "summary": "Deliverable 1 (comment correction) shipped; deliverable 2 (the census) came back ZERO in-repo suppliers, so per the dispatch I stopped and did NOT remove the read arm. (a) Spec re-measured myself on the installed @objectstack/spec@17.2.0 via DashboardSchema.safeParse, with a lit control: control {name,label,widgets} ACCEPT; {...control, title:'T'} REJECT unrecognized_keys(title)@root; extra reading {...control, header:{title:'T'}} REJECT unrecognized_keys(title)@header. 20 keys, label present, title absent. NOTE the control matters: the card's 'control (no title) ACCEPT' only holds with label present, because label is REQUIRED - a bare {name,widgets} control fails on label, not on title. (b) CENSUS, every probe declaration/AST-shaped, every zero paired with a control lit in the same run. SUPPLY: [1] all 546 tracked JSON parsed, structural walk for dashboard-shaped nodes (has widgets array) -> 9 nodes, 6 carry root title, all examples/schema-catalog/src/schemas/plugin-dashboard/filtered-dashboard*.json; those are objectui COMPONENT schemas (type:'dashboard', no name) consumed by SchemaRenderer->DashboardRenderer, never by DashboardView (which resolves by name out of useMetadata().dashboards); probe discriminates - it also reported the 3 nodes without title and their key sets. [2] TS-AST over all 4137 tracked ts/tsx, object literals with a widgets array initializer -> 78 literals, 12 with title (controls in same run: label 8, name 21); of the 12, 9 are test fixtures, 1 is a Zod declaration (DashboardConfigSchema), and the 2 non-test hits are plugin-dashboard/src/index.tsx:350 (ComponentRegistry defaultProps for the dashboard-grid COMPONENT, not a document) and plugin-designer/src/pages/DashboardDesignPage.tsx:39 (seed literal reachable ONLY on the !dashboard branch, which early-returns 'not found' and never calls handleChange/saveSchema - cannot persist). [3] TS-AST assignment expressions writing a title member: 12 sites, NONE on a dashboard document (document.title, out.title in chart normalizers, this.schema.title in the builder); control X.label = ... lit at 20 sites. [4] the surface that DOES write dashboard documents, app-shell/src/views/metadata-admin/dashboard-schema.ts, derives its entire form from spec DashboardSchema via z.toJSONSchema and calls label 'dashboard display name rendered as a dedicated control' - it structurally cannot emit title. => SUPPLY POINTS: ZERO. READ POINTS: TS-AST census of every expr.title / expr['title'] read in non-test source = 436 sites; grouping by receiver isolates 5 with a dashboard-ROOT receiver: app-shell/src/views/DashboardView.tsx:178 (headerSrc.title, this card), plugin-dashboard/src/DashboardRenderer.tsx:947 (schema.title || schema.label - its comment is ALREADY accurate, calling title 'the legacy objectui spelling', framework#1878/#1891), plugin-dashboard/src/DashboardGridLayout.tsx:394, plugin-designer/src/DashboardEditor.tsx:467, plugin-designer/src/pages/DashboardDesignPage.tsx:138. FIXTURES: DashboardView has exactly ONE test file, packages/app-shell/src/views/DashboardView.modalTarget.test.tsx; its fixture is {name:'sales_overview', label:'Sales Overview', widgets:[]} - no title (control: label lit in that file at :91). No test anywhere pins DashboardView's title arm. (c) ONE CORRECTION TO THE CARD'S PREMISE (the claim itself is fully confirmed): the card reasons the arm 'still works for a host that passes a previewSchema carrying title'. There is no host channel - DashboardView takes one prop, dataSource; previewSchema is a useMemo LOCAL to this view (lines 129-142) producing a widget-pruned copy of dashboard. So headerSrc.title IS dashboard.title in every case, i.e. a key on the stored sys_dashboard document, which is exactly the surface the spec refuses. This sharpens the card rather than weakening it: the arm is not preview-only, it is legacy-document-only. The new comment states this, since the old one is what invited the misreading. (d) The census therefore pushes toward disposition 1 ONLY, and explicitly NOT toward disposition 2: with 5 read sites and an out-of-tree document population (dashboards are served by the platform; DashboardRenderer dates the spelling to framework#1878/#1891), deleting the arm is a behaviour change on documents this repo cannot measure. The named precedents #5830 and #5852 both retired keys that NOTHING read; this one is read at 5 sites. Clause-2 stayed 'no': comment text only, no type/schema/export/runtime path touched, no needs:contract-review. PR is draft and says Refs #7509, not a closing keyword, so the card stays open for the ruling.", "tests": "Union re-run on the final commit 90abd60c (git rev-parse --short HEAD after the last commit). Heavy runs went through /home/user/objectstack/scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-7509-objectui set before the first attempt; exit codes captured by redirecting to a file BEFORE reading, never through a pipe. (1) pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build -> 'os-verify-lock: VERDICT command-exit 0' (dependency closure built before any test/typecheck). (2) pnpm exec vitest run packages/app-shell/src/views/DashboardView.modalTarget.test.tsx (from the repo ROOT, repo-relative path, no '--' - the two silent-green traps in objectui AGENTS.md) -> 'Test Files 1 passed (1)', 'Tests 5 passed (5)', VITEST_EXIT=0. (3) pnpm --filter @object-ui/app-shell run type-check -> TYPECHECK_EXIT=0; the script name echoed as '> @object-ui/app-shell@17.6.0 type-check' so it was not a zero-match no-op (objectui spells it type-check, hyphenated); and against the 'typecheck excludes your files' trap, tsc --noEmit --listFiles confirms views/DashboardView.tsx IS in the checked set (grep -c = 1). (4) pnpm exec eslint packages/app-shell --format json -> ESLINT_EXIT=0, 1062 files checked, 0 errors, 2868 pre-existing warnings; the edited file has 10 warnings, all pre-existing no-explicit-any / set-state-in-effect on lines the comment merely shifted by +13. (5) node scripts/check-control-bytes.mjs -> exit 0, verdict line 'check-control-bytes: OK (scanned 6195 tracked text file(s); skipped 85 binary)'. (6) node scripts/check-spec-symbol-derivation.mjs -> exit 0, '1344 files scanned against 4959 spec export names'. (7) node scripts/check-changeset-presence.mjs -> exit 0, 1 changeset with EMPTY frontmatter, 'the explicit exemption and a complete answer to this gate'. (8) node scripts/check-changeset-no-major.mjs -> exit 0. (9) node scripts/check-changeset-overwrite.mjs -> exit 0. Plus a manual control-byte self-scan on both changed files: grep -naP for the control-byte class -> no match. GATE DERIVATION: scripts/pm/dispatch-gates.mjs lives in objectstack and answers only about ITS OWN tree, so objectui's gate family was derived by hand from this repo's package.json check:* scripts and .github/workflows/ - the diff touches one released-package source file plus one .changeset, which selects control-bytes, spec-symbols (the comment cites @objectstack/spec) and the three changeset gates; no i18n key, doc, dist, skill or registration surface is touched. DECLARED NARROWING: the repo-wide 'pnpm lint' (turbo run lint, every package) was narrowed to packages/app-shell, with all three pieces of evidence - (i) the checked population comes from eslint's own config resolution, not my guess; (ii) the count 1062 is read from --format json output; (iii) eslint.config.js enables NO type-aware linting (its languageOptions carries no parserOptions.project and no projectService; control: 'rules' occurs 10x in that file, so the grep shape is live), so every rule is per-file and a comment edit cannot move the verdict on an untouched file. CI runs the full farm regardless. NO ablation was run: the change is comment text only, so there is no behaviour to ablate.", "mcp_calls": "2 - one create_pull_request, one add_issue_comment. Everything else went through git and the public-repo zero-quota page payload (issue body + PR body read-back).", "open_questions": [ { "question": "The census found ZERO in-repo suppliers of a root `title` on a dashboard DOCUMENT, but 5 read sites and an out-of-tree document population. Should `DashboardView`'s `title` read arm (and the sibling arms in DashboardRenderer / DashboardGridLayout / DashboardEditor / DashboardDesignPage) be retired under ADR-0049, and if so, all five together or DashboardView's alone?", "options": [ "A - Keep all five arms, ship the comment correction only (this PR). Cost: the legacy spelling stays live and undocumented as a contract, so a future reader re-litigates it. Benefit: zero behaviour change; every stored document that still carries `title` keeps its header. Who is affected: nobody.", "B - Retire DashboardView's arm alone (`headerSrc.title` and its fallback), leaving the four sibling arms. Cost: a stored dashboard document carrying only `title` and no `label` loses its console header and falls through to the raw `name`; and it splits the behaviour - the SAME document keeps its title inside DashboardRenderer's own header and in the designer, so the two surfaces disagree. Who is affected: any platform-served `sys_dashboard` document with `title` and no `label`.", "C - Retire all five arms as one class under ADR-0049, exactly the shape of the #5830 / #5852 retirements, with a changeset that names the loss. Cost: same document population loses its header on every surface at once, and it is a behaviour change this repo cannot measure because the documents live on the platform, not here. Benefit: one spelling, `label`, everywhere; the spec's refusal and the renderer's behaviour finally agree.", "D - Measure first, decide after: query the platform for `sys_dashboard` documents carrying a root `title`, then pick B or C on a real population count rather than on this repo's (zero) evidence." ], "recommendation": "D, then C if the platform count is zero. Long-term soundness (weight >=50%): one spelling is the contract-first answer and C is the shape the two same-class precedents already set, so C is where this should land - but the precedents differ on the ONE fact that matters, and the difference is not decorative: #5830 and #5852 retired keys that NOTHING read, whereas this key is read at 5 live sites, so the liveness evidence those retirements rested on is exactly what is missing here. Real business need: measured, the in-repo pull is zero in both directions - nothing supplies `title`, and no test pins it - so neither keeping nor deleting serves a demonstrated need on the evidence I can reach; the only population that could is out of tree, which is precisely why D comes first and why option A is not merely inertia. Making AI-authored metadata hard to get wrong: this is what already works and is the reason C is the destination - the spec REFUSES `title` by name at publish, so no AI-authored dashboard can acquire the key going forward; the renderer arms are backward compatibility for stored history only, never an authoring hatch, and this PR's comment now says so at the read site. Startup scope discipline: no surface expands under any option; C and D are both contractions, and D costs one query. B I would not recommend under any measurement - the same document rendering with a title in the designer and without one in the console is a worse contract than either endpoint. Deciding without D means guessing at a population that exists outside this repo, and the direction of that guess is the maintainer's call, not mine." } ], "out_of_scope_findings": [] }Generated by Claude Code
Generated by Claude Code
os-project-manager commented
on Sep 3, 2026 CollaboratorAuthorMore actions交付 1 已落地,交付 2 的普查做完了 —— ⛔ 转
needs-user-decisiondomain:ui执行席,sessionsession_01EMrWaQw3XS5DxTHxp4yRyC。PR #7520 已合并(
152227c59),按内容确认探针 读数 注释是否还把 title归给 spec0 对照: headerSrc.title读取臂是否仍在1(仍在,本 PR 不动它) 新注释是否写出「写它会 422」这条有用事实 :177、:181-182——unrecognized_keys(title)/422 INVALID_METADATA都写进去了⭐ 新注释没有停在「spec 不声明它」,而是写出了下一个读者真正需要的那句:写
title从保存路由拿到的是 422,不是标题。普查结论:零仓内供应者
三条声明/AST 形状探针,每个零都配了同一次运行里点亮的对照:JSON 结构走查(546 文件 / 9 个 dashboard 形状节点,6 命中)、TS-AST 对象字面量(4137 文件 / 78 个含
widgets数组的字面量,12 命中)、TS-AST 赋值表达式(12 命中,没有一个在 dashboard 文档上)。分诊后 6 个 JSON 全是SchemaRenderer消费的组件 schema(无name),够不到按name取的DashboardView;12 个 TS 里 9 个测试夹具、1 个 zod 声明,剩两个一个是组件注册的defaultProps、一个在!dashboard分支里而该分支直接 early-return 不可能持久化。真正写 dashboard 文档的作者面metadata-admin/dashboard-schema.ts由 specDashboardSchema经z.toJSONSchema派生,结构上发不出title。⚠️ 本卡正文有一处措辞已被证伪正文写「still works for a host that passes a
previewSchemacarryingtitle」。没有那个 host 通道:DashboardView({ dataSource })只有一个 prop,previewSchema是它自己的useMemo(:129),所以headerSrc两条路都源自dashboard。⇒ 那个 arm 不是 preview 兜底,是遗留存储文档在这一处的唯一读点。这不削弱本卡,是锐化它。⛔ 待裁的就是一件事:五处
title读点是否同波退休删臂之所以不是执行层面的小事,有一条决定性的:
读点 文件 1 app-shell/views/DashboardView.tsx:178← 本卡2 plugin-dashboard/DashboardRenderer.tsx:9473 plugin-dashboard/DashboardGridLayout.tsx:3944 plugin-designer/DashboardEditor.tsx:4675 plugin-designer/pages/DashboardDesignPage.tsx:138⇒ 只删第 1 处,会让同一份遗留文档在设计器里有标题、在控制台里没有。 两个界面对同一份数据给出不同答案,比「都保留」和「都删」中的任何一端都糟。⇒ 要么五处同波,要么都不动。这使它明确是设计裁定而非修复。
而且本卡援引的两个同类先例(#5830
DashboardComponentSchema.aria、#5852DashboardConfig.aria)退休的都是无人读的键;这个有五处读点。它们赖以成立的活性证据,恰恰是这里缺的那一样。选项(实现者给出,本席按独立读数排序)
- D → 先测,再按结果选 C(实现者推荐,本席同意):先查平台侧带根
title的sys_dashboard存量文档有多少。⇒ 本仓的证据(零)只覆盖本仓;唯一能决定的那个总体在仓外。测一次很便宜。 - C —— 五处同波按 ADR-0049 退休,changeset 明写损失。⭐ 若平台侧计数为零,这是终点:一个拼写、
label,spec 的拒绝面与渲染器行为终于一致。 - A —— 只改注释(即已落地的 docs(app-shell): DashboardView's header comment stops attributing
titleto the spec #7520),不动任何 arm。零行为变更;代价是遗留拼写继续以未声明的契约形态活着,下一个读者再论一次。 - ⛔ B(只删第 1 处)—— 本席与实现者独立给出同一判断:任何测量结果下都不推荐。 理由即上表。
⛔ 本席不裁:方向取决于一个本仓测不到的总体,而猜那个方向不是执行席的权限。
⛔ 本卡不带
pm:queue、assignee 已清空 —— 裁定前不进队列,也不再显示为有人在做。
Generated by Claude Code
- D → 先测,再按结果选 C(实现者推荐,本席同意):先查平台侧带根
Maintainer ruling recorded — C: retire all five
titleread arms as one class under ADR-0049; one PR; the changeset names the loss.needs-user-decision→pm:queuein the same stroke.Director seat, summon 14 (
session_01LsEjuNMPitCHwEfYftZ1um, GitHubos-warren). Provenance: maintainer, live PM chat, 2026-09-04, decision batch #29, verbatim 「同意」 on the presented recommendation (C, one payment, no staged D first — the maintainer's standing 2026-08-27 principle 「项目在创业阶段,用户也很少,短期不考虑渐进」; fallback A; ⛔ B refused, as the implementer and the seat independently concluded). Premises re-verified onorigin/main24e027eat 05:24Z:DashboardView.tsx:191(headerSrc.title),DashboardGridLayout.tsx:394(schema.title || …label), and the sibling arms inDashboardRenderer,DashboardEditor,DashboardDesignPagenamed on 5529202530; PR #7520 (comment correction) merged152227c59.The ruling
- The five dashboard-root
titleread arms retire together:app-shell/views/DashboardView.tsx,plugin-dashboard/DashboardRenderer.tsx,plugin-dashboard/DashboardGridLayout.tsx:394,plugin-designer/DashboardEditor.tsx,plugin-designer/pages/DashboardDesignPage.tsx.label(required onDashboardSchema) is the only header source, thenname. ⛔ Widget-levelwidget.title(DashboardWidget.title, the spec'sI18nLabel) is a different, declared key and is untouched — the dev distinguishes root from widget arms by receiver, not by grep. - The spec already refuses root
titleby name, so no authored document can acquire it; what retires is the legacy-document compatibility. Population outside this repo is unmeasured; the bound that makes C acceptable: a spec-valid stored document always carrieslabel, so a legacy document with both showslabelfrom now on (a visible, legitimate change), and a document withtitleand nolabelwas already invalid. - Each arm gets a refusal-shaped pin in the finding(types):
DashboardComponentSchema.ariadeclares a key the spec tombstoned and no renderer reads — stale "Aligned with @objectstack/spec AriaPropsSchema" claim #5830 / finding(types): designer-surfaceDashboardConfig.aria/DashboardConfigSchema.ariadeclare a{ label, description }aria object nothing reads — and the panel they document does not consume them #5852 form (a document carrying roottitlerenders thelabelheader, not thetitle), and the changeset says in operator language: "a stored dashboard whose header came from a legacy roottitlenow shows itslabel".
Execution constraints, for the
domain:uiseat- One PR, five files, M; Clause-②: no (renderer behaviour on a key the contract already refuses; no accept set moves) — the seat re-judges from the diff at claim time.
- If, at claim time, the seat can cheaply get a platform-side count of
sys_dashboarddocuments carrying roottitle(the D reading), it is recorded on this card as context; it does not gate the ruling. - Serial constraints: any open PR on the five files (the plugin-dashboard renderer has been hot this week — re-measure).
Ruling authority: maintainer 2026-09-04 (batch #29). Related: PR #7520 · #5830 · #5852 · #7014 / #7513 (the gate blind spot this came out of) · ADR-0049.
Generated by Claude Code
- The five dashboard-root
Filed unassigned by the
domain:uidev seat working objectui#7014 (sessionsession_01EMrWaQw3XS5DxTHxp4yRyC) — recording, not claiming. Found by the same instrument that produced #7014's corrections; out of that card's scope (different package, different contract), so it is filed rather than ridden along.Dedupe: searched before filing; the control returned live, on-topic results (27 hits incl. #7279, #7293, and the closed same-class sibling #5830), so a nil result here is a reading. No open card covers this.
The claim
packages/app-shell/src/views/DashboardView.tsx:173:Measured on the installed
@objectstack/spec@17.2.0DashboardSchemahas notitlekey, and refuses it by name:Its 20 keys are
_lock, _lockDocsUrl, _lockReason, _lockSource, _packageId, _packageVersion, _provenance, aria, columns, dateRange, description, gap, globalFilters, header, label, name, performance, protection, refreshInterval, widgets—label, nottitle.Why it is worth a card rather than a comment edit
The runtime code around it reads
headerSrc.titlethrough anas anycast, so the read itself compiles and the fallback chain (titlethenlabelthenname) still works for a host that passes apreviewSchemacarryingtitle. The defect is that the comment attributes the key to the spec, which makes it read as authorable dashboard metadata — and authoring it produces a 422 rather than a header.Two dispositions, not obviously the same job, which is why this is not self-evident:
titleis a preview/host-supplied key the spec refuses, and that authored metadata must uselabel. Cheapest, changes nothing.titleread should exist at all. The same class was retired twice on this surface already (finding(types):DashboardComponentSchema.ariadeclares a key the spec tombstoned and no renderer reads — stale "Aligned with @objectstack/spec AriaPropsSchema" claim #5830DashboardComponentSchema.aria, finding(types): designer-surfaceDashboardConfig.aria/DashboardConfigSchema.ariadeclare a{ label, description }aria object nothing reads — and the panel they document does not consume them #5852DashboardConfig.aria), both on ADR-0049 declared-but-unenforced grounds. If no host actually suppliestitle, the read and its fallback arm are dead.⛔ Not proposing a disposition; a census of who supplies
previewSchema.titleis the missing input.Same blind spot as objectui#7014
scripts/check-spec-symbol-derivation.mjscannot see this. Rule 2 reads only the doc comment attached to a declaration; this claim sits in a comment inside a function body. And even where a claim is read, it is validated only at symbol granularity —DashboardSchemais a live spec export, so a citation ofDashboardSchema.titlepasses the dangling-citation precision rule although.titleis not a key of it. The gate reports identical numbers with this defect present.