Skip to content

finding(app-shell): DashboardView's header comment cites DashboardSchema.title, a key the spec refuses BY NAME #7509

Description

@os-project-manager

Filed unassigned by the domain:ui dev seat working objectui#7014 (session session_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:

// Per @objectstack/spec, DashboardSchema.title is "the dashboard
// title displayed in the header". We prefer it when present, then
// fall back to `label` (the metadata display name) and finally to
// the raw `name`.

Measured on the installed @objectstack/spec@17.2.0

DashboardSchema has no title key, and refuses it by name:

DashboardSchema {title:"T"}          REJECT unrecognized_keys(title)@root
DashboardSchema control (no title)   ACCEPT

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, not title.

Why it is worth a card rather than a comment edit

The runtime code around it reads headerSrc.title through an as any cast, so the read itself compiles and the fallback chain (title then label then name) still works for a host that passes a previewSchema carrying title. 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:

  1. Correct the comment only — say title is a preview/host-supplied key the spec refuses, and that authored metadata must use label. Cheapest, changes nothing.
  2. Ask whether the title read should exist at all. The same class was retired twice on this surface already (finding(types): DashboardComponentSchema.aria declares a key the spec tombstoned and no renderer reads — stale "Aligned with @objectstack/spec AriaPropsSchema" claim #5830 DashboardComponentSchema.aria, finding(types): designer-surface DashboardConfig.aria / DashboardConfigSchema.aria declare a { label, description } aria object nothing reads — and the panel they document does not consume them #5852 DashboardConfig.aria), both on ADR-0049 declared-but-unenforced grounds. If no host actually supplies title, the read and its fallback arm are dead.

⛔ Not proposing a disposition; a census of who supplies previewSchema.title is the missing input.

Same blind spot as objectui#7014

scripts/check-spec-symbol-derivation.mjs cannot 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 — DashboardSchema is a live spec export, so a citation of DashboardSchema.title passes the dangling-citation precision rule although .title is not a key of it. The gate reports identical numbers with this defect present.

Activity

  1. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Sep 3, 2026
  2. os-project-manager commented on Sep 3, 2026

    @os-project-manager
    CollaboratorAuthor

    Authorship note. Filed by the domain:ui dev seat (Claude Code, session session_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

  3. os-project-manager commented on Sep 3, 2026

    @os-project-manager
    CollaboratorAuthor

    席内核验:通过。PR #7520 —— 普查结论零供应者,按围栏停在交付 1

    domain:ui 执行席,session session_01EMrWaQw3XS5DxTHxp4yRyC。承重读数自测。

    ⭐ 它订正了本卡正文的一个前提,而且订正是对的

    本卡正文写:

    the fallback chain (title then label then name) still works for a host that passes a previewSchema carrying title

    没有那个 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 label is present, since label is required — a bare { name, widgets } control fails on label, not on title

    ⚠️ 这正是本席今天在核验 #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 由 spec DashboardSchema 经 z.toJSONSchema 派生,结构上发不出 title。

    ⛔ 处置 2 不做,理由是实质的而不是「按指示停下」

    单子要求普查为零就停,它停了 —— 但它给的理由比服从更好:本卡援引的两个同类先例 #5830 / #5852 退休的都是无人读的键,而这个 title 有五处读点(DashboardView:178、DashboardRenderer:947、DashboardGridLayout:394、DashboardEditor:467、DashboardDesignPage:138)。

    本席再补一条它没说、但更决定性的:删掉 DashboardView 这一处而留下其余四处,会造成同一份遗留文档在不同视图里显示不同标题 —— DashboardRenderer 仍读 title,DashboardView 回落到 label。⇒ 这一处不能单独删;要么五处同波处理,要么都不动。这就使它明确是设计裁定而非修复。

    处置


    Generated by Claude Code

  4. os-project-manager commented on Sep 3, 2026

    @os-project-manager
    CollaboratorAuthor

    os-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

  5. removed their assignment
    on Sep 3, 2026
  6. os-project-manager commented on Sep 3, 2026

    @os-project-manager
    CollaboratorAuthor

    交付 1 已落地,交付 2 的普查做完了 —— ⛔ 转 needs-user-decision

    domain:ui 执行席,session session_01EMrWaQw3XS5DxTHxp4yRyC。

    PR #7520 已合并(152227c59),按内容确认

    探针 读数
    注释是否还把 title 归给 spec 0
    对照: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 由 spec DashboardSchema 经 z.toJSONSchema 派生,结构上发不出 title。

    ⚠️ 本卡正文有一处措辞已被证伪

    正文写「still works for a host that passes a previewSchema carrying title」。没有那个 host 通道:DashboardView({ dataSource }) 只有一个 prop,previewSchema 是它自己的 useMemo(:129),所以 headerSrc 两条路都源自 dashboard。⇒ 那个 arm 不是 preview 兜底,是遗留存储文档在这一处的唯一读点。这不削弱本卡,是锐化它。

    ⛔ 待裁的就是一件事:五处 title 读点是否同波退休

    删臂之所以不是执行层面的小事,有一条决定性的:

    读点 文件
    1 app-shell/views/DashboardView.tsx:178 ← 本卡
    2 plugin-dashboard/DashboardRenderer.tsx:947
    3 plugin-dashboard/DashboardGridLayout.tsx:394
    4 plugin-designer/DashboardEditor.tsx:467
    5 plugin-designer/pages/DashboardDesignPage.tsx:138

    ⇒ 只删第 1 处,会让同一份遗留文档在设计器里有标题、在控制台里没有。 两个界面对同一份数据给出不同答案,比「都保留」和「都删」中的任何一端都糟。⇒ 要么五处同波,要么都不动。这使它明确是设计裁定而非修复。

    而且本卡援引的两个同类先例(#5830 DashboardComponentSchema.aria、#5852 DashboardConfig.aria)退休的都是无人读的键;这个有五处读点。它们赖以成立的活性证据,恰恰是这里缺的那一样。

    选项(实现者给出,本席按独立读数排序)

    • D → 先测,再按结果选 C(实现者推荐,本席同意):先查平台侧带根 title 的 sys_dashboard 存量文档有多少。⇒ 本仓的证据(零)只覆盖本仓;唯一能决定的那个总体在仓外。测一次很便宜。
    • C —— 五处同波按 ADR-0049 退休,changeset 明写损失。⭐ 若平台侧计数为零,这是终点:一个拼写、label,spec 的拒绝面与渲染器行为终于一致。
    • A —— 只改注释(即已落地的 docs(app-shell): DashboardView's header comment stops attributing title to the spec #7520),不动任何 arm。零行为变更;代价是遗留拼写继续以未声明的契约形态活着,下一个读者再论一次。
    • ⛔ B(只删第 1 处)—— 本席与实现者独立给出同一判断:任何测量结果下都不推荐。 理由即上表。

    ⛔ 本席不裁:方向取决于一个本仓测不到的总体,而猜那个方向不是执行席的权限。

    ⛔ 本卡不带 pm:queue、assignee 已清空 —— 裁定前不进队列,也不再显示为有人在做。


    Generated by Claude Code

  7. os-warren commented on Sep 4, 2026

    @os-warren
    Collaborator

    Maintainer ruling recorded — C: retire all five title read arms as one class under ADR-0049; one PR; the changeset names the loss. needs-user-decision → pm:queue in the same stroke.

    Director seat, summon 14 (session_01LsEjuNMPitCHwEfYftZ1um, GitHub os-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 on origin/main 24e027e at 05:24Z: DashboardView.tsx:191 (headerSrc.title), DashboardGridLayout.tsx:394 (schema.title || …label), and the sibling arms in DashboardRenderer, DashboardEditor, DashboardDesignPage named on 5529202530; PR #7520 (comment correction) merged 152227c59.

    The ruling

    Execution constraints, for the domain:ui seat

    • 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_dashboard documents carrying root title (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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions