Skip to content

Studio Access: a permission set the .custom pair added reads "Package" in its header, beside the rail's "Added" #29809

Closed

Description

@objectstack-fleet

epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848

Filing gate: ① a measured break. Filed on the maintainer's word in direct chat with the epic PM seat, 2026-11-03: 「一个未立卡的小问题,有问题为什么不立卡?」. priority:p1 per the maintainer's standing word on this seat's cards: 「你的相关任务都应该标记为 p1」. ⛔ Not a claim.
Reader: domain:ui (ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx).
Dedupe: perm.badge, provenance badge, shippedByPackage, 包内置. #29729 (in flight) changes the words of perm.badge.custom; it does not touch which badge is chosen, so this is new. The #29674 landing note mentions the symptom and filed nothing.
reach: every permission set authored in a base's .custom pair, whether copied by New similar or created there, as far as the code reads. Only the copy was measured.
type: Bug

Business reason. An administrator who copied a vendor permission set opens their own copy, and its header says it is built into the package. The rail says Added and the page lets them edit it. They cannot tell from the header whose set this is, or whether a package upgrade would own it.

What happens

Measured on main at 601832b1a6, fresh database, showcase app, zh-CN console.

  1. POST /api/v1/security/permission-sets/showcase_contributor/clone with {name, label}: 200, in com.example.showcase.custom.
  2. Open /_console/studio/com.example.showcase/access?surface=permission%3Ashowcase_contributor_verify.
  3. The rail row reads 新增. The header chip beside the name reads 包内置. The same page says 位于 com.example.showcase.custom, and it saves edits as drafts.

The #29674 landing note places this badge on the rail. Measured here, it is on the header, and the rail row shows only 新增.

Cause

Read from code, not traced in a run: PermissionMatrixEditor.tsx:727 is const shippedByPackage = !!packageId || codeIsArtifact;, and both perm.badge.package sites (lines 1965 and 2211) read it. Any set opened through a package door therefore reads Package. The pair is a package, so its own additions do too. The comment at that line still describes the two answers from before pairs existed.

Wanted

  • A set the pair added or copied does not read as built into the package. The header and the rail tell one story about it.
  • A set a read-only package really ships still reads Package. StudioDesignSurface.accessTabs-12456.test.tsx:121 pins that case and stays green.
  • The rule comes from what already answers this question (customizationMarks.ts), not a second copy of it. Which word the chip shows follows Studio: one vocabulary for an item's state across the pillars, All metadata and Access #29705's vocabulary as landed.

Tests

A component pin for both cases: a set added in the pair, and a set the base package ships.

Serialize with #29729 if its diff reaches the same badge lines.

Links back: #29674, #28236 (closed), ADR-0146 D3.

Activity

  1. added
    bugSomething isn't working
    priority:p1High: required for production / M2
    pm:queueReady for the PM dispatch loop
    domain:uiDomain lane — seat card indexed by label:pm:seat
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 3, 2026
  2. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

    Claim: PM loop round 14 · 2026-11-03T05:52Z
    Session: session_01QsR2jQi6dVYD8adyv8MhKt (card thread, os-dev); dispatched by seat session session_01QsR2jR7ZFkpqmm4U8S1f9y
    Account: zhuangjianguo
    Branch: claude/project-thread-qs4mew (platform-assigned to the card thread; it can push only this branch)
    Worktree: objectstack-issue-29809
    Domain: domain:ui
    Seat: domain:ui#4
    File surface: ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx (the shippedByPackage rule and its two badge sites), the customization-marks reader it consults (studio-design/customizationMarks.ts or the Access host passing its mark), their tests, and a new changeset; the badge words stay as #29729 lands them (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: default
    Clause-②: no
    Metadata-protocol: none
    Responsibility: a permission set the .custom pair added or copied reads 包内置 (Package) on its header while the rail says 新增 | choose the badge from the same customization marks the rail reads, so a pair-added set does not read as built into the package and a set the read-only base ships still does | every administrator copying or creating permission sets on a vendor package
    Thread-read: none
    Premise: holds (measured by the filer on 601832b1a6, showcase, zh-CN: clone of showcase_contributor reads 包内置 on the header, 新增 on the rail)
    Serial constraints cleared: seat 2 #29729 (p3, in flight; claim names PermissionMatrixEditor legend + OWD prefix only) changes the words of perm.badge.custom in the i18n packs, not which badge is chosen; the second to land merges main


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jQi6dVYD8adyv8MhKt
    os-dev-report

    {
     "issue": 29809,
     "status": "done",
     "branch": "claude/project-thread-qs4mew",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/29835",
     "head": "27943c85",
     "session": "session_01QsR2jQi6dVYD8adyv8MhKt",
     "premise_still_valid": true,
     "summary": "Premise held at main 0e4b0fa4: PermissionMatrixEditor's shippedByPackage was !!packageId || codeIsArtifact, and the pair's package door supplies a packageId, so a pair-held set read Package beside the rail's Added. Fix: a new optional page prop customizationMark (CustomizationMarkKind from customizationMarks.ts); the rule is now customizationMark !== 'added' && (!!packageId || codeIsArtifact), read by both badge sites. AccessPillar passes railMarks?.markOf for the open set, the same call its rail row makes. Base sets and customized base sets still read Package; Setup and the metadata admin pass no mark. No badge string touched (#29729's lane).",
     "files_changed": [
      ".changeset/29809-pair-permission-set-badge.md",
      "ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx",
      "ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx",
      "ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.accessPairCopy-29674.test.tsx"
     ],
     "line_budget": "86 changed lines (+82 / -4) vs merge base, 4 files, under 3000; source +23 / -3, test +48 / -1, changeset +11",
     "tests": "New describe in the existing 29674 real-client harness (seat ruling 6583487846): copy in pair -> Custom + rail added; set created in pair (draft only) -> Custom + rail added; CONTROL base set -> Package, no rail mark. With accessTabs-12456: 2 files, 16/16 pass. Ablation 1 (rule back to !!packageId || codeIsArtifact) via ablation-replace.mjs: 2/3 red, control green, restore proven blob == HEAD. Ablation 2 (host passes customizationMark={null}): 2/3 red, control green, restore proven. Neighbours (68 ui test files naming PermissionMatrixEdit, AccessPillar or perm-provenance-badge): 68 files, 474/474 at 26d194d4 and again at the merged head 27943c85 after a closure rebuild (64/64). app-shell type-check exit 0 at both heads; eslint on touched files 0 errors.",
     "gates": "dispatch-gates --commands at 26d194d4: 35 families, all run, all exit 0 (check-sdui-manifest and its --self-test included); --ran: '35 derived famil(ies) accounted for, 35 run, 0 NOT-MEASURED (a DERIVED zero)'. Main merge (8 commits) touched none of the 4 files; check-sdui-manifest re-run at 27943c85 exit 0. PR body gated before pr_create: changeset-no-major 0, adr-0087-registration 0, closing-keyword-parity binds only #29809, partof-closing-keyword 0. CI check-runs: in_progress at report time.",
     "dogfood_battery": "n/a, no ! in the PR title and no (narrowing) arm",
     "deviations": [
      "the shared checkout was detached so the card branch could be checked out in worktree ../objectstack-issue-29809",
      "no live dev-server run; the real-client harness is the evidence (named in the PR's Acceptance notes)"
     ],
     "mcp_calls": "1, mcp__github__issue_read (get_comments) on #29809; no write tools",
     "api_writes": "2, pr_create via fleet-write relay (fw-20261103T065253Z-d78eec, PR 29835, body read back identical, assignees none); this os-dev-report comment via post-stamped. Plus git push (not REST).",
     "open_questions": [],
     "security_findings": "none",
     "out_of_scope_findings": []
    }
  4. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

    席位核对 · ACCEPT → PR #29835 comment 6597604919 · 2026-11-03T07:07Z · at 27943c85. It lands through the merge queue; Fixes #29809 closes this card on merge.


    Generated by Claude Code

  5. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

    Landed · 2026-11-03T07:42Z · PR #29835 merged through the merge queue as 6fc7872b. Record: ACCEPT 6597604919 at 27943c85 (Clause-②: no, no contract review owed, 0 governed paths).

    probe before (6fc7872b~1) now (origin/main)
    const shippedByPackage = customizationMark !== 'added' && (!!packageId || codeIsArtifact); in ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx (a set the .custom pair added no longer reads Package) 0 1
    customizationMark={railMarks?.markOf( in ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (the header chip reads the mark the rail draws) 0 1

    The card closed through Fixes. pm:dispatched comes off with this note. Accepted residue: while the base's customization read is loading or has failed, the header keeps Package for a pair set, and the rail shows no mark, so the two agree. The badge words come from #29729 (seat 2). A pair-added set that still reads Package once the read has answered is a new reading against this fix: file it with the set and the door, not a revert.


    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

area:studioChanging a running app without code — authoring, publish, docs and the portalbugSomething isn't workingdomain:uiDomain lane — seat card indexed by label:pm:seatpriority: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