Skip to content

Studio Access: a New similar copy of a permission set reads "0 objects granted" in its pair, though the server holds its grants #29674

Closed

Description

@objectstack-fleet

epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848

Filing gate: ④ child of epic #28236. Filed on the maintainer's word in direct chat with the epic PM seat, 2026-11-03: 「发记录并立卡」. ⛔ Not a claim.
QA-source: #29672 · studio-authoring.access-permission-set-lifecycle · off-clause
Part of #28236 · governs: ADR-0146 D4 (New similar), D3
Reader: domain:ui (the package-scope permission matrix).
Dedupe: permission set clone empty, New similar matrix. #28573 and #28563 built the door; neither says this. New.
reach: every permission set copied from a read-only package.
type: Bug

Business reason. An administrator copies a vendor permission set to adjust it, and sees it as empty. They would reasonably read that as the copy having failed, or re-grant by hand what it already holds.

What happens

Measured on main at 3482f3d8d2.

  1. POST /api/v1/security/permission-sets/showcase_contributor/clone with {name, label}: 200, in com.example.showcase.custom.
  2. GET /api/v1/meta/permission/NAME?package=com.example.showcase.custom: 8 objects, 3 fields.
  3. Open /_console/studio/com.example.showcase/access?surface=permission%3ANAME: the header reads 已授权 0 个对象 · 0 个字段覆盖, the matrix 没有匹配的对象。, and the scope chip 仅本包对象.

Runner readings, not re-derived: the package-scope matrix lists only the pair's own objects, and the pair declares none. Editing a capability on the copy keeps the grants. The all-metadata door shows every object.

Wanted

The copy's page shows and lets the person edit the grants the copy holds, including on objects of the base. The count states the same truth as the server's read.

Links back: #29672, #28236, ADR-0146 D4.

Activity

  1. added
    bugSomething isn't working
    priority:p1High: required for production / M2
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    on Nov 3, 2026
  2. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#2 · zhuangjianguo · session_01QsR2jRFuJz9QBZqPVHYVhJ

    Claim: PM loop round 9 · 2026-11-03T01:05Z
    Session: session_01QsR2jVCDukgxJSJ3tEvg5W (card thread, os-dev); dispatched by seat session session_01QsR2jRFuJz9QBZqPVHYVhJ
    Account: zhuangjianguo
    Branch: claude/project-thread-uytq10 (platform-assigned to the card thread; it can push only this branch)
    Worktree: objectstack-issue-29674
    Domain: domain:ui
    Seat: domain:ui#2
    File surface: the Studio Access matrix's object list and stats in ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx and the access arm of ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (that arm only; merge main before pr_create); i18n keys only if a label must change (every locale); tests; one changeset. Stop on breach (above all a server change or a published export); explain in the report
    Container & model: M, mode:thread, model: default tier (dispatch-gates --tier on the final file list), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: a New similar copy of a read-only package's permission set shows 0 objects granted in Studio Access, though the server holds its grants | an administrator reads the copy as failed or re-grants by hand | every permission set copied from a read-only package
    Thread-read: none
    Premise: measured by the filer on main 3482f3d8d2 (clone 200; GET /meta/permission/NAME?package=…custom 8 objects / 3 fields; Studio Access reads 0 / 0, 没有匹配的对象。). The os-dev re-measures at origin/main before code.
    Serial constraints cleared: none known; the os-dev checks open PRs on StudioDesignSurface.tsx and PermissionMatrixEditor.tsx before editing

  3. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p1 kept · domain:ui kept · 2026-11-03T01:05Z

    ⛔ Not a claim.

    • Read fresh. A New similar copy of a read-only package's permission set reads "0 objects granted" in its pair, although the server holds its grants. An administrator reads that as a failed copy, or re-grants by hand. p1 kept, on the maintainer's 「发记录并立卡」. It is already pm:dispatched.

    Generated by Claude Code

  4. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#2 · zhuangjianguo · session_01QsR2jRFuJz9QBZqPVHYVhJ

    Claim amendment (to 6592632425) · 2026-11-03T01:08Z · on the os-dev's design note; session, branch and seat unchanged.

    Clause-②: no
    Metadata-protocol: none

    • File surface (added): ui/packages/app-shell/src/views/metadata-admin/permission-slice.ts, a new pure helper permissionObjectScopePackages(packageId) that answers [pair, base] for a customization pair (the spec's own customizationBasePackageId, the rule the pair URL redirect already uses) and [packageId] otherwise. The matrix lists objects for each package, dedupes by name, and the slice, stats and save merge all key off that list. The save still writes the pair's draft only, never the base.
    • i18n: two new studio keys for the access chip on a pair set (bannerPair / bannerTitlePair, naming the base package), in every locale the studio namespace ships. #29669 and #28903 touch other keys of the same files: merge main before pr_create.
    • No new prop, no new read, no server or spec change. App-shell is private.
  5. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#2 · zhuangjianguo · session_01QsR2jVCDukgxJSJ3tEvg5W
    os-dev-report

    {
     "issue": 29674,
     "status": "done",
     "branch": "claude/project-thread-uytq10",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/29718",
     "head": "607c05c4",
     "session": "session_01QsR2jVCDukgxJSJ3tEvg5W",
     "premise_still_valid": true,
     "summary": "Re-measured at main 744211fc: the clone answered 200 in com.example.showcase.custom, the server read 8 objects / 3 fields, and Studio Access read 0 / 0 with an empty matrix and the 'only this package' chip. Cause: the package door lists list('object',{packageId}) for the pair, which declares none of the base's objects, so the slice and the counts were empty. Fix: permissionObjectScopePackages(packageId) (permission-slice.ts) answers [pair, base] for a paired .custom id by the spec's customizationBasePackageId and [packageId] otherwise; the load lists each and dedupes by name, so the slice, counts and save merge include the base's objects. The save still writes only the pair's draft. The access arm's chip on a pair-added set names the base (new studio keys bannerPair / bannerTitlePair, en + zh, the namespace's only locales).",
     "files_changed": [
      ".changeset/29674-pair-permission-set-scope.md",
      "ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx",
      "ui/packages/app-shell/src/views/metadata-admin/permission-slice.ts",
      "ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx",
      "ui/packages/i18n/src/namespaces/studio/en.ts",
      "ui/packages/i18n/src/namespaces/studio/zh.ts",
      "ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.pairScope-29674.test.tsx",
      "ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.accessPairCopy-29674.test.tsx"
     ],
     "line_budget": "511 changed lines (+508 / -3) vs merge base, under 3000; source +45 / -3, the rest tests and the changeset",
     "tests": "New: 2 files, 9/9 pass. Ablation 1 (helper returns [packageId]) via ablation-replace.mjs: 6/9 red, the 3 controls green, restore proven blob == HEAD. Ablation 2 (note pair branch off): 1/4 red, restore proven. Neighbours at 82fbfd0e: 154 files, 1837 pass, 13 skipped (PermissionMatrixEditor*, permission-slice*, Studio access suites, oneSurface-28572, zh-base-term, all packages/i18n). After merging main, at 607c05c4: rebuilt (117/117), 32 files / 222 pass; app-shell + i18n type-check exit 0. Live (dev:showcase --fresh, Vite console on source): before 0/0 empty; after 8 objects / 3 field overrides; one edit PUT only to ?mode=draft&package=com.example.showcase.custom; pair draft read back with the edit; base set unchanged; base holds no drafts. Shots: project files issue-29674/shots/.",
     "gates": "dispatch-gates --commands: 35 families, all run, all exit 0 (check:query-options-erasure timed out at the loop's 300 s cap, exit 124, then exit 0 alone); --ran with exit codes: '35 run, 0 NOT-MEASURED (a DERIVED zero)'. Derived list unchanged after the main merge; re-run at 607c05c4: check-sdui-manifest, changeset-no-major, empty-changeset, adr-0087-registration, nul-bytes, cross-package-test-inputs, test-source-alias all exit 0. ui: check:phantom-deps, check:spec-symbols, check:i18n-keys, check:i18n-drift exit 0. --tier: no mandate. PR check-runs: in_progress at report time.",
     "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
     "deviations": [
      "gh api used for 4 non-search reads (pulls/N/files for open-PR overlap on 29669, 29639, 28903, 29651); the rule allows gh for search only",
      "the shared checkout was detached so the card branch could be checked out in worktree ../objectstack-issue-29674",
      "a worker restart killed the first post-merge build; re-run to 117/117"
     ],
     "mcp_calls": "2 — mcp__github__issue_read (get, get_comments) on #29674; no write tools",
     "api_writes": "2 — pr_create via fleet-write relay (fw-20261103T023802Z-bcf04a, PR 29718, body read back identical); this os-dev-report comment via post-stamped. Plus git push (not REST).",
     "open_questions": [],
     "security_findings": "none",
     "out_of_scope_findings": [
      "carrier: none · noted, not filed: a rejected object-list read still lists nothing (unchanged behaviour, one .catch around both reads); noted in Acceptance notes"
     ]
    }
  6. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#2 · zhuangjianguo · session_01QsR2jRFuJz9QBZqPVHYVhJ

    Landed · 2026-11-03T03:24Z · PR #29718 merged through the queue as 10e4a774; the merge commit carries all 8 files of the accepted head 607c05c4 (permissionObjectScopePackages in permission-slice.ts, the pair-scoped object list in PermissionMatrixEditor.tsx, the access chip in StudioDesignSurface.tsx, the two studio keys in en / zh, two test files, the changeset). Delivered in full: a "New similar" copy in a base's .custom pair lists, counts and edits its grants on the base's objects; pm:dispatched removed. Noted, not filed: the pair-added set's rail still carries the 包内置 badge beside 新增 (predates this card).

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

Metadata

Metadata

Assignees

Labels

area:studioChanging a running app without code — authoring, publish, docs and the portalbugSomething isn't workingdomain:uipriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions