Skip to content

Setup › Permission set › Add user: the user picker lists names only, so two people of one name cannot be told apart #27433

Closed

Description

@objectstack-fleet

domain:ui#2 · os-warren · session_01JQwxbXpF772qWJjojJvRXw

Follow-up from #27410 (PR #27427, seat ACCEPT 6489766088). The os-dev reported it in that PR's acceptance notes.

What happens

On a Setup permission-set page, Assigned users › Add opens RecordPickerDialog on sys_user with no columns (ui/packages/app-shell/src/views/metadata-admin/AssignedUsersSection.tsx, the picker near L612). The picker draws only its default display column, the name. An administrator cannot tell two people of the same name apart, or confirm the account before granting the set. Yet the assigned-user rows on the same section already show each person's email under the name (≈L579).

This is the same gap #27410 closed for Setup › Position › Add holder.

Fix shape (reuse #27427)

  • Pass columns for name and email, with en/zh headers from the section's own copy, and objectSchema set to sys_user from the useMetadata() objects the section already holds. Add no new fetch.
  • Add no permission check of its own: the picker's readableColumns rule decides what is drawn.

Acceptance

  • The picker draws a Name column and an Email column.
  • CONTROL: choosing people still writes the sys_user_permission_set grant by name ({ user_id, permission_set }). It still offers the active organization's members only, and the AI-seat cap refusal still shows inline.
  • CONTROL: under a real PermissionProvider that denies sys_user.email, only the name column is drawn and no email text appears.
  • Test against the real RecordPickerDialog, with a columns ablation that goes red.

Activity

  1. added
    pm:queueReady for the PM dispatch loop
    domain:uiDomain lane — seat card indexed by label:pm:seat
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Oct 29, 2026
  2. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · os-bill · session_01Utp6CbDAucNyQ4UtzCJKyh

    Claim: PM loop round 1
    Session: session_01Utp6CbDAucNyQ4UtzCJKyh
    Account: os-bill
    Branch: claude/project-thread-8i0z2y (the card thread's designated push branch, the recorded platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-27433
    Domain: domain:ui
    Seat: domain:ui#4
    File surface: ui/packages/app-shell/src/views/metadata-admin/AssignedUsersSection.tsx, one new test beside it, root .changeset/; @object-ui/i18n packs only if a new header key is needed (then Clause-②: yes (widening)) (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier on 968cacfd: no path-derived mandate), effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the Add user picker on a Setup permission set draws a Name and an Email column (reusing the #27427 shape), with the card's CONTROL lines pinned against the real RecordPickerDialog
    Thread-read: none
    Premise: holds
    Serial constraints cleared: none — no open PR touches AssignedUsersSection.tsx

    Dispatched 2026-10-29T23:19Z to a card thread of the seat's project; the order lives in the project. ⛔ The thread posts no claim and writes no assignee.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · os-bill · session_01Utp6CazvDXxebLfghuZZ7t
    os-dev-report

    {
      "issue": 27433,
      "status": "done",
      "branch": "claude/project-thread-8i0z2y",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/27808",
      "session": "session_01Utp6CazvDXxebLfghuZZ7t",
      "premise_still_valid": true,
      "summary": "Setup permission set > Assigned users > Add user now opens RecordPickerDialog with columns name + email (headers from the section's own en/zh copy, no new i18n key) and objectSchema = sys_user from the useMetadata() objects the section already holds; no new fetch and no permission check of its own. Same shape as PR #27427. Premise measured on 968cacfd: the picker had no columns and the assigned rows already drew email.",
      "tests": "head 3b0005b0: new file AssignedUsersSection.pickerColumns-27433.test.tsx against the real RecordPickerDialog + real PermissionProvider: Test Files 1 passed, Tests 5 passed (lock VERDICT command-exit 0). All 44 test files naming AssignedUsersSection (the new file included), re-run on 3b0005b0: Test Files 44 passed, Tests 332 passed (VERDICT command-exit 0). pnpm --filter @object-ui/app-shell run type-check: VERDICT command-exit 0 (first run exit 2 on TS2322 SchemaLike vs a Record of string to unknown; fixed in 3b0005b0 by the precedent's cast). Ablation via scripts/ablation-replace.mjs on c0a3253b (before 3b0005b0, a type-only cast change): delete the columns prop, anchor 1 -> 0, blob 6e003bf1 -> 495a0d0e, the column test red (1 failed / 4 passed, CONTROLs green), restored blob == HEAD, git diff HEAD empty. app-shell tests import src, so no dist rebuild leg.",
      "gates": "local derived set on 3b0005b0, exit codes recorded before any pipe: node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0 ; node scripts/check-adr-0087-registration.mjs --self-test :: exit 0 ; node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0 ; node scripts/check-closing-keyword-parity.mjs :: exit 0 ; node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 ; node scripts/check-comment-mask-corpus.mjs :: exit 0 ; node scripts/check-empty-changeset.mjs --base origin/main :: exit 0 ; node scripts/check-empty-changeset.mjs --self-test :: exit 0 ; node scripts/check-sdui-manifest.mjs :: exit 0 ; node scripts/check-sdui-manifest.mjs --self-test :: exit 0 ; node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0 ; node scripts/release-pending-publish.mjs --self-test :: exit 0 ; pnpm --dir ui exec vitest run scripts/ :: exit 0 ; pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0 ; pnpm check:changeset-gate-self-tests :: exit 0 ; pnpm check:closed-ceremony-text :: exit 0 ; pnpm check:cross-package-test-inputs :: exit 0 ; pnpm check:dispatcher-error-vocabulary :: exit 0 ; pnpm check:driver-memory-census :: exit 0 ; pnpm check:engine-double-contract :: exit 0 ; pnpm check:gitlink-declared :: exit 0 ; pnpm check:nul-bytes :: exit 0 ; pnpm check:pm-changeset-deadline-census :: exit 0 ; pnpm check:published-files :: exit 0 ; pnpm check:query-options-erasure :: exit 0 ; pnpm check:refd-timer-probe :: exit 0 ; pnpm check:skill-identifier-liveness :: exit 0 ; pnpm check:test-source-alias :: exit 0 ; pnpm check:tier-file-adoption :: exit 0 ; pnpm check:type-check-coverage :: exit 0 ; pnpm check:type-check-debt :: exit 0 ; pnpm check:undeclared-dep-imports :: exit 0 ; pnpm check:watch-hint-literal :: exit 0 ; pnpm check:where-matcher :: exit 0. dispatch-gates --ran: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. CI families: the PR's check-runs, in_progress at report time.",
      "line_budget": "206 changed lines (+206/-0 at 3b0005b0 vs merge base 968cacfd; 3 files), under the 3000 human-merge threshold",
      "files_changed": [
        "ui/packages/app-shell/src/views/metadata-admin/AssignedUsersSection.tsx",
        "ui/packages/app-shell/src/views/metadata-admin/AssignedUsersSection.pickerColumns-27433.test.tsx",
        ".changeset/27433-permission-set-user-picker-email.md"
      ],
      "deviations": [
        "origin/main moved 13 commits past the base before the PR; none touches the three changed files or RecordPickerDialog, so the branch was not merged with it (AGENTS.md multi-agent §10 pre-PR pull skipped on zero overlap)",
        "the session-context's after-PR assign + review request step was skipped per the dispatch order (no assignees, no review request)",
        "the harness PR-subscription posture is not taken; CI convergence is the seat's per os-dev.md"
      ],
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "1 — mcp__claude-code-remote__get_session (read of this session's id); 0 GitHub MCP calls",
      "api_writes": "2 — relay pr_create (POST pulls, PR #27808); post-stamped issue comment on #27433 (this report). Plus git push (not REST).",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Report taken 2026-10-30T00:04Z.

  4. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · os-bill · session_01Utp6CbDAucNyQ4UtzCJKyh

    ACCEPT → PR #27808 comment 6511624958 · 2026-10-30T00:13Z


    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

Labels

domain:uiDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions