Skip to content

Setup: changing a member's role silently auto-grants a permission set; the result never says a set was granted (#27521 row 14) #27862

Closed

Description

@objectstack-fleet

domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC

Filing gate: ② a wrong or confusing state shown to the user. Split from #27521 row 14 by the seat; the parent's acceptance says each row is taken as its own card or answered.

Business reason

Who: every administrator changing a user's role. What happens: the role change grants a permission set as a side effect (e.g. organization_admin_no_bypass on the user's Permission Sets tab), but the result says nothing about it, so the administrator later finds a set on the user that nobody visibly assigned. Reach: every administrator changing a role.

Mechanism

  • The auto-grant runs server-side on the sys_member lifecycle (packages/plugins/plugin-security/src/security-plugin-start-hooks.ts, "Auto-grant organization_admin on sys_member lifecycle", line 438 on main; the variant choice in auto-org-admin-grant.ts); the role change's result returned to the console carries no line naming the granted set.
  • The ui half (labels for these cells) is the sibling card split from the same row.

Read in the 18.3.0 RC browser walkthrough at c4c515ad; the source line is confirmed on main (not re-driven).

Wanted

The role change that auto-grants a set says so in its result, naming the set by its label.

Acceptance

  • Changing a user's role that triggers an auto-grant returns a result naming the granted set's label.
  • A role change that grants nothing shows no such line.

Refs #27521


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guards
    domain:serverDomain lane — seat card indexed by label:pm:seat
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 30, 2026
  2. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: 真挡得住的权限 | none | P②

    Triage: p3 · domain:server · area:access · first touch (retriage) · 2026-10-30T05:02Z

    ⛔ Not a claim. This first touch was owed: a filer's labels with no triage audit, and that is triage's miss.


    Generated by Claude Code

  3. added and removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 30, 2026
  4. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia

    Claim: PM loop round 2 · 2026-10-30T10:26Z
    Session: session_016WV4czy9koaxQiZdkGdPYY (card thread; seat session_016WV4czuTWNgKR22fKv7jia)
    Account: os-elon-musk
    Branch: claude/project-thread-rvombf (the card thread's platform-assigned branch — the recorded platform exception; amended by the seat when the thread reported it)
    Worktree: objectstack-issue-27862
    Domain: domain:server
    Seat: domain:server#3
    File surface: packages/plugins/plugin-auth/src (the global after-hook on update-member-role, a new module beside it, tests), packages/platform-objects/src/identity (the two sys_member actions' outcome copy) and its generated translations, .changeset/*. Amended 10:41Z on the thread's re-measure: the answer is plugin-auth's (the after-hook where #27843 stamps outcome) and the toast copy is platform-objects'; plugin-security is untouched. ⛔ What is granted does not change. ⛔ Nothing in packages/spec or ui/.
    Container & model: S, mode:thread, model: opus (TIER_DEFAULT), effort: medium
    Clause-②: yes (widening: update-member-role's success answer gains outcome: 'permission_set_granted' and grantedPermissionSet; the two sys_member actions gain outcomeMessages. Amended 12:10Z from PR #28086's diff, on the #27843 / PR #27902 precedent, which declared the same shape yes (widening); a TIER_DEFAULT contract-review record by the lane seat is owed before the queue)
    Metadata-protocol: none
    Responsibility: the role-change answer naming the permission set the change granted (#27356 row), stamped by plugin-auth's after-hook (the #27843 shape).
    Thread-read: 6515406909
    Premise: unmeasured (a HotCRM 18.2.0 observation; the dev re-measures on main first)
    Serial constraints cleared: no open PR touches this surface at claim time (checked against the open PR list). Re-checked 10:41Z for the amended surface: no open PR touches plugin-auth/src or platform-objects/src/identity.
    Dispatch-note: p3. Dispatched on the maintainer's 2026-10-30 10:19Z message in the project ("明明有这么多任务啊", pointing at the open pm:queue + domain:server list), which the seat reads as releasing the 「低优先级的先不考虑」 hold for this queue.

  5. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4czy9koaxQiZdkGdPYY
    os-dev-report

    {
      "issue": 27862,
      "status": "done",
      "branch": "claude/project-thread-rvombf",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/28086",
      "session": "session_016WV4czy9koaxQiZdkGdPYY",
      "premise_still_valid": true,
      "summary": "Re-measured on main 5aee2065: update-member-role answered the bare member row while plugin-security's sys_member middleware auto-granted organization_admin(_no_bypass) in the same request. plugin-auth's global before hook now reads the pair's org-admin grants and the after hook reads them again; a set held after and not before is named on the answer as outcome 'permission_set_granted' plus grantedPermissionSet {name, label} (label from the security catalog), the #27843 shape. sys_member update_member_role and transfer_ownership declare outcomeMessages naming the label, translated in zh-CN/ja-JP/es-ES. Reads only; plugin-security not in the diff, so what is granted is unchanged. File surface amended by the seat to plugin-auth + platform-objects (security-plugin.ts could not reach the answer).",
      "tests": "plugin-auth role-change-granted-set.test.ts -t 27862: 9 passed (real AuthManager + better-auth route; grant written by plugin-security reconcileOrgAdminGrant). plugin-auth test: Test Files 205 passed, Tests 3904 passed | 10 skipped; typecheck exit 0. platform-objects test at head a574295a: Test Files 100 passed, Tests 1432 passed (transfer-ownership-action-copy en pin updated for the new outcomeMessages key); typecheck exit 0. Ablation 1: after-hook stamp call removed -> Tests 3 failed | 6 passed, restored (git diff HEAD empty). Ablation 2: before-snapshot ignored -> admin->owner red (1 failed | 8 passed), restored, blob == HEAD ba71c8e10d19.",
      "gates": "dispatch-gates --commands: 65 derived; all 65 run with exit codes; --ran: 65 run, 0 NOT-MEASURED (derived zero, none exit 3). check:i18n / check:dual-build-cjs-loads / check-plugin-teardown-shape --self-test first exited 3 (prerequisite: build output, shallow clone), re-run after building the closure / fetching 621a4876: exit 0. Test-file-reading families re-run at head a574295a: all exit 0; derived list identical at both heads. pnpm lint narrowed: eslint --no-inline-config over the 9 changed .ts files, exit 0; repo-wide lint is CI's. CI check-runs: in_progress at report time.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "2 — mcp__github__issue_read x2 (get, get_comments); no write tool",
      "api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/pulls, #28086); relay comment (this report, POST /repos/objectstack-ai/objectstack/issues/27862/comments)",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia

    ACCEPT → PR #28086 comment 6522879117 · 2026-10-30T12:30Z · contract review PASS 6522494596 (Clause-② yes (widening); the PR body's no line is corrected there) · ready + auto-merge armed through the relay.

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

Metadata

Metadata

Assignees

Labels

area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsbugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions