Skip to content

[Decision] The rail's green 「+」 looks like an add button but is a status mark: what should a customization mark look like? #30070

Closed

Description

@objectstack-fleet

epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff

The maintainer: 「等我决定的都要立卡,并且从业务的角度给我具体解释和我沟通」 (2026-11-04). Measured by the seat on main 63b86b385d, on the example CRM unless noted. No domain:* label is set: triage routes this card.

The question

Studio's left rail marks a customized row with a small icon: a green filled square with a plus means 新增, added in the customization package. It is not a control. A person clicks it, nothing happens, and it sits right beside an item they could not add to the menu. The maintainer did exactly this: 「还有导航上一个加号图标什么意思,点了也没反应」.

Governing text: ui/packages/app-shell/src/views/studio-design/CustomizationMark.tsx:40-44 (#29693 compacted the mark to a glyph so it never takes the row's label). No ADR fixes the glyph.

Measured

Drawn temporarily in the live rail on the automation pillar, row width 223 px:

Style Mark width Room for the name
Today's green filled plus 18 px 113 px
The word 新增, no background 30 px 105 px
A green package glyph 18 px 113 px

A dot is out: the automation rail already uses dots for 已启用, 未在此运行, 已停用.

Options

  • A. Words, no background: 新增 for added and 定制 for customized. Costs 8 px, under one character of the name.
  • B. A non-plus glyph: same width, but the meaning has to be learned or hovered.
  • C. Keep the plus.

Recommendation: A

四轴分析

实际业务需求。 运营在左栏看到绿色加号会以为能点,这个误会已经发生过一次。每次打开定制过的应用都会看到。

项目长远合理性。 状态就该长得像状态。A 不用记,也不会和操作混淆。

防 AI 写错。 不涉及元数据,只影响 AI 操作界面时的判断:文字比图标更不会被认错。

创业阶段不扩散。 只改一个组件的样式,没有新能力。

棱 A B C
业务 强 中 弱
长远 强 中 弱
防错 强 中 弱
不扩散 强 强 强

Re-check

git grep -n "added: Plus" origin/main -- ui/packages/app-shell/src/views/studio-design/CustomizationMark.tsx

Activity

  1. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff

    The maintainer, 2026-11-04: 「30079这种不是应该在元数据应用中自己去开发自定义操作吗?你的意见是批量换负责人放到内核吗?其他全部同意」.

    Ruling: option A. Customization marks use the words 新增 and 定制 with no background, and keep the tooltip. Clicking stays row selection only. needs-user-decision is removed; triage routes this card.

  2. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p3 kept · domain:ui · 2026-11-04T13:15Z

    ⛔ Not a claim.

    • Read fresh. Ruled A: the customization marks on the rail read 新增 and 定制, with no background, and a click stays row selection. p3 kept.

    Generated by Claude Code

  3. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#5 · os-sales · session_01L6bhgVwQZbHRRM9CaXeKif

    Claim: PM loop round 2
    Session: session_01L6bhgVwQZbHRRM9CaXeKif
    Account: os-sales
    Branch: claude/project-thread-p3zei2 (card thread of this project; a thread can push only its designated branch — measured platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-30070
    Domain: domain:ui
    Seat: domain:ui#5
    File surface: ui/packages/app-shell/src/views/studio-design/CustomizationMark.tsx, StudioRailCustomizations.tsx and the tests that pin the mark (incl. StudioDesignSurface.oneSurface-28572.test.tsx) + ui/packages/i18n/src/namespaces/studio/{en,zh}.ts + one root .changeset/. InterfacesNavRail.tsx / StudioDesignSurface.tsx only if required (PR #30401 of domain:ui#2 edits them); ⛔ packages/**.
    Container & model: M, mode:thread, model: default — dispatch-gates --tier: no path-derived mandate, effort: high
    Clause-②: yes
    Metadata-protocol: none
    Responsibility: the compact customization mark (CustomizationMark.tsx) draws a filled green block with a plus icon that reads as an add button but is a status mark | none: no other affordance names a row's customization at a glance | everyone who opens a customized app in Studio (the maintainer clicked it once and nothing happened)
    Ruling-ref: 6631229752 「Ruling: option A. Customization marks use the words 新增 and 定制 with no background, and keep the tooltip. Clicking stays row selection only.」
    Thread-read: 6631605075
    Premise: holds
    Serial constraints cleared: #30238, #30088 and #30177 are closed; no open PR edits CustomizationMark.tsx, StudioRailCustomizations.tsx or the 28572 test; PR #30401 (domain:ui#2, #30046) edits InterfacesNavRail.tsx / StudioDesignSurface.tsx, which this card avoids. The InterfacesNavOverrideMark button (the 恢复原版 popover) keeps working.

    Scope: the ruled option A only. Clause-② yes (widening) for a new short studio i18n key: the seat's TIER_DEFAULT review before the queue. Dispatch order lives in the card thread's opening message.

  4. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#5 · os-sales · session_01L6bhgXtD8kC2LpK5YoB2sK
    os-dev-report

    {
      "issue": 30070,
      "status": "done",
      "branch": "claude/project-thread-p3zei2",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30468",
      "session": "session_01L6bhgXtD8kC2LpK5YoB2sK",
      "premise_still_valid": true,
      "summary": "Ruled option A implemented. CustomizationMark's compact branch (every pillar rail row via RailCustomizationMark, and InterfacesNavOverrideMark's popover button) now prints one short coloured word with no background and no glyph: customized reads the new studio key engine.customizationMark.customizedShort (zh 定制, en Custom), added reads the existing engine.customizationMark.added (新增 / Added). role img, accessible name (full label) and tooltip unchanged; no handler, so a click stays row selection. Mechanism hypothesis held as written (18x18 filled block, empty textContent pinned by the 28572 test).",
      "tests": "On cabd8ba8 (head b3864c84 is tree-identical: evidence commit + removal). pnpm --dir ui exec vitest run over the 9 test files that name the mark + i18n studio-namespace and studio-namespace-lazy: Test Files 11 passed (11), Tests 230 passed (230), lock VERDICT command-exit 0. Ablation 1 (ablation-replace.mjs, anchor x1 to x0): compact word to {null} -> 1 failed / 26 passed (expected '' to be 'Custom'); restored, blob == HEAD, git diff HEAD empty. Ablation 2: compact classes given filled KIND_CLASS back -> 1 failed / 26 passed (not to match bg-); restored, blob == HEAD. pnpm --filter @object-ui/i18n --filter @object-ui/app-shell type-check (tsc --noEmit + tsconfig.test.json): VERDICT command-exit 0. Live rig examples/app-crm + console vite, zh-CN and en-US at 1440: before 18px filled + svg; after transparent, no svg, widths 定制 22 新增 22 Custom 40 Added 34; nav-override popover with 恢复软件包原版 still opens; clicking the 新增 mark selects its row.",
      "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at cabd8ba8: 35 derived, each run, all exit 0 (incl. pnpm --dir ui exec vitest run scripts/: 170 files passed 2 skipped, 4985 tests passed 2 skipped; check:type-check-debt exit 0). --ran reconciliation: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN. Outside the derived list: pnpm --dir ui run check:spec-symbols exit 0; eslint on the 5 changed source files exit 0 (warnings on unchanged lines only); pnpm check:new-line-citations (ui) 0 new, exit 0. CI check-runs on PR 30468: in_progress at report time.",
      "dogfood_battery": "n/a — no ! in the PR title and Clause-② is yes (widening), no (narrowing) arm",
      "mcp_calls": "4 — reads only: mcp__github__issue_read x3 (issue 30070 get, get_comments x2), mcp__github__pull_request_read x1 (PR 30442 body as a layout reference); zero MCP writes",
      "api_writes": "2 relay writes + 1 git push: git push -u origin claude/project-thread-p3zei2; fleet-write pr_create (run 42028931858, PR 30468, draft, no assignees, no labels); this os-dev-report comment via post-stamped.mjs",
      "open_questions": [
        {
          "question": "English word for the compact customized mark: Custom (40 px, chosen) or Customized (61 px, cut the selected row to 'Convert Lea…' on the 223 px automations rail)?",
          "options": [
            "A Custom (as shipped)",
            "B Customized (one en row change)"
          ],
          "recommendation": "A, because the ruling's point is a short status word that never takes the row's name, and zh 定制 is the same short form"
        }
      ],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: none · InterfacesNavRail.tsx InterfacesNavOverrideMark doc comment still says 'the compact customized glyph' — stale wording only, file left untouched because PR 30401 (domain:ui#2) edits it; noted in the PR's Acceptance notes, not filed"
      ]
    }
  5. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#5 · os-sales · session_01L6bhgVwQZbHRRM9CaXeKif

    Landed at 2026-11-05T13:18Z: PR #30468 merged as 0c7e95aff5 (seat ACCEPT 6658596635 on head b3864c84, TIER_DEFAULT contract review PASS 6658291542), Fixes #30070. The merge read 2026-11-05T13:17Z on the PR.

    probe reading
    git grep -c customizedShort origin/main -- ui/packages/app-shell/src/views/studio-design/CustomizationMark.tsx 1 (the compact mark prints its word on main)
    card state closed (completed) by the merge

    State change: pm:dispatched removed. Ruling A (6631229752) is implemented in full; nothing remains on the card.

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions