Skip to content

List sort picker offers hidden system fields: 队列 and an untranslated "Search Index" appear beside the business fields #30037

Closed

Description

@objectstack-fleet

epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff

The maintainer: 「缺陷 2-7 立卡」 (2026-11-04).

Filed by the record-page epic seat from a browser evaluation of the Console on main 63b86b385d (example CRM, zh-CN, dev admin). An independent reviewer ran the pass and the seat re-checked the evidence named below. No domain:* label is set: triage routes this card.

Business reason

A rep sorting a list picks from a menu that includes 队列 and "Search Index". Neither means anything to them, and the second is English on a Chinese screen. Sorting by the search index returns an order nobody can explain, with no hint why.

Reproduce

Open 线索 → 排序 → 添加排序 → open 排序依据. Measured by the seat on /apps/com.example.crm/crm_lead: 创建时间, 更新时间, 队列, 线索名称, 邮箱, 电话, 公司, 职位, 状态, 来源, 线索评分, 备注, Search Index. The filter panel's field list on 商机 showed neither.

Code readings on 63b86b385d

  • ui/packages/plugin-list/src/ListView.tsx:5077-5099: filterFields drops a field declared hidden, keeping it only when a held condition names it.
  • :5182-5217: sortFields walks the same candidateFields and has no hidden check.
  • packages/spec/src/data/injected-system-column-provenance.ts:178-183 and packages/objectql/src/search-companion.ts:316-320: queue and __search are both hidden: true.

So this is one list that missed the rule its neighbour follows.

Acceptance

  1. The sort picker leaves out a field declared hidden, unless the current sort already names it. That row stays visible and removable, as today's inUse path does for other fields.
  2. The hide-fields, group and row-color lists are read for the same gap, and any that share it are fixed here, with the list of what was read in the PR.
  3. A test pins the sort picker.

To check while here

The reviewer also reported __search in Studio's formula 插入字段 and in the validation 参与字段 list. On its screenshots the seat could confirm only 队列 in 插入字段. Measure these, and fix them here if real. A hidden field a formula may legitimately read needs the implementer's judgement, so report it rather than removing it silently.

Re-check

git grep -n "sortPicksRelationalField" origin/main -- ui/packages/plugin-list/src/ListView.tsx

Activity

  1. 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-04T10:59Z

    ⛔ Not a claim.

    • Read fresh. The list sort picker offers hidden system columns (队列, an untranslated "Search Index"). The provenance data already exists in spec (injected-system-column-provenance.ts), so the picker should read it. p3 kept.

    Generated by Claude Code

  2. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#2 · os-bill · session_01Utp6Cb5R6JDdfyvtj3dPR2

    Claim: PM loop round 1 · 2026-11-05T07:24Z
    Session: session_01Utp6Cb5R6JDdfyvtj3dPR2 (seat); dev = card thread session_01Utp6CY1ikAq74XRbNdsyUC
    Account: os-bill
    Branch: claude/project-thread-8vldlz (harness-pinned card thread branch; the claude/issue-N-slug convention does not apply to a project card thread)
    Worktree: objectstack-issue-30037
    Domain: domain:ui
    Seat: domain:ui#2
    File surface: ui/packages/plugin-list/src/** (ListView sort fields, a shared field-visibility helper if any), their tests, one root .changeset/ (stop on breach; explain in the report)
    Container & model: S, not mechanical (M treatment), mode:thread, model: default tier (opus) — dispatch-gates --tier: no path-derived mandate, effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — UI defect/enhancement in ui/** owned by this lane; no platform path covers it; reached by every console/Studio user
    Thread-read: 6628963650
    Premise: holds (ListView.tsx sortFields ~:5274-5308 has no hidden check; filterFields ~:5174 has one; origin/main ff3f83b)
    Serial constraints cleared: none (no domain:ui in-flight claim names ui/packages/plugin-list; #30220 is plugin-form/plugin-kanban)

    Dispatch order: /mnt/project-files/ui-seat2/dispatch-30037.md (project files).

  3. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#2 · os-bill · session_01Utp6Cb5R6JDdfyvtj3dPR2
    os-dev-report

    Card thread session_01Utp6CY1ikAq74XRbNdsyUC · branch claude/project-thread-8vldlz · draft PR #30384 · head 26c80600

    {
      "issue": 30037,
      "status": "done",
      "branch": "claude/project-thread-8vldlz",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30384",
      "session": "session_01Utp6CY1ikAq74XRbNdsyUC",
      "premise_still_valid": true,
      "summary": "Premise held at 1c537831: filterFields drops a definition-hidden field unless a held condition names it, sortFields walked the same candidateFields with no hidden check. One module-level predicate, isDeclaredHidden(defs, field), beside canReadField; filterFields and addableFields now call it (behaviour unchanged) and sortFields offers a field only when it is readable and not hidden. A hidden field the current sort names is kept by the existing in-use exception, listed disabled (removable only); a hidden lookup no longer raises the relational hint. Acceptance item 2 read: hide-fields columns, Group editor and Row color all read allFields (the view's declared columns, which the grid draws), and addableFields already excluded hidden fields; no gap, nothing changed there.",
      "tests": "Red first: new pins with ListView.tsx at its base (commit 91cec45d): Test Files 2 failed (2), Tests 6 failed | 6 passed (12), each failure 'Search Index' listed or the relational hint drawn for the hidden lookup. Green: same two files 12/12 after the fix; final head 26c80600 sortRemovableOnly-11943 + sortFieldRead-11943 + filterFieldList-11810 + fieldListRead-11984: Test Files 4 passed (4), Tests 50 passed (50), lock VERDICT command-exit 0. Whole plugin-list package (145 files import ListView) on c3b69a91: Test Files 189 passed (189), Tests 1813 passed (1813), lock VERDICT command-exit 0; the merge brought no ui/ path. turbo type-check --filter=@object-ui/plugin-list on 26c80600: Tasks 53 successful, 53 total (first run red TS6133 on an unused binding this PR left, fixed in 26c80600). No ablation beyond the red-first run: the pins are the reverse verification of the one behaviour changed.",
      "gates": "dispatch-gates --commands on 26c80600 vs merge base fdad1786: 35 derived, all 35 run, each exit 0 (incl. node scripts/check-sdui-manifest.mjs and pnpm --dir ui exec vitest run scripts/: 170 passed, 2 skipped files; 4985 passed, 2 skipped tests). --ran reconciliation: 35 derived / 35 run / 0 NOT-MEASURED / 0 UNRUN. Also pnpm --filter @object-ui/plugin-list lint exit 0 (0 errors), root eslint --no-inline-config on the 3 touched files exit 0, pnpm check:changeset-fixed exit 0, pnpm --dir ui check:new-line-citations 0 new, check-nul-bytes exit 0. CI check-runs on #30384: not yet read at report time.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "line_budget": "4 files, +68 / -11 vs fdad1786; production code +31/-9 in ListView.tsx (about half of it comment), the rest pins and a changeset",
      "deviations": [
        "Studio formula 插入字段 (ObjectFieldInspector fieldOptions) and validation 参与字段 (ObjectValidationsPanel cross_field list) live in ui/packages/app-shell, outside the order's file surface: read, not measured in a running Studio, not changed; written up in the PR's Acceptance notes.",
        "Card and PR reads went through gh api REST GETs, not MCP; no write through either.",
        "No subscribe_pr_activity on #30384 and no assignee or review request: the seat hands off.",
        "Commit trailers are the model-free pair; one merge commit subject names origin/main only."
      ],
      "files_changed": [
        ".changeset/30037-sort-picker-hidden-fields.md",
        "ui/packages/plugin-list/src/ListView.tsx",
        "ui/packages/plugin-list/src/__tests__/ListView.sortFieldRead-11943.test.tsx",
        "ui/packages/plugin-list/src/__tests__/ListView.sortRemovableOnly-11943.test.tsx"
      ],
      "mcp_calls": "0 — no MCP GitHub tool called",
      "api_writes": "3 — git push to claude/project-thread-8vldlz (4 pushes, one branch), relay pr_create (#30384, run 41996722241, 7799 bytes sent and stored identical, draft), this os-dev-report comment through post-stamped",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: PR #30384 Acceptance notes · noted, not filed — Studio formula Insert field lists every sibling field of the object draft with no hidden check; whether the draft carries queue/__search not measured; a formula may legitimately read some hidden columns, so this is a judgement for the app-shell owner",
        "carrier: PR #30384 Acceptance notes · noted, not filed — validation rule cross_field field list shows every field; the panel already reads hidden for its new-rule default but the checkbox list does not filter"
      ]
    }

    Report taken 2026-11-05T08:44Z.

  4. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#2 · os-bill · session_01Utp6Cb5R6JDdfyvtj3dPR2

    ACCEPT → PR #30384 comment 6654603880 (head 1b1f7fa6). Landing through the merge queue.

  5. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#2 · os-bill · session_01Utp6Cb5R6JDdfyvtj3dPR2

    Landed · 2026-11-05T11:43Z · PR #30384 merged as 75a5c3ef1 through the merge queue (seat ACCEPT on the merged head; landing authorized by the maintainer in the seat thread, 11:29Z). Card state: closed. pm:dispatched removed.

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