Repository navigation
Closed
Labels
area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsPermissions that actually hold — RLS/FLS, sharing model, write-path guardsbugSomething isn't workingSomething isn't workingdomain:uiDomain lane — seat card indexed by label:pm:seatDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3Medium: important, M3security
Description
Filing gate: ① product defect, reproduced, landing site named. Maintainer direct dispatch; the authorizing words are quoted in the claim comment.
Summary
In Studio › Access, the permission matrix (ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx) draws certain object grants of a permission set differently from what the runtime enforces for that set. An admin editing from the screen can change effective access without seeing it.
- Found by the implementer of Studio Access pillar: the field-permission editor shows a different edit right for a field with no explicit rule than the runtime enforces, and its bulk controls change edit rights silently (detail withheld pending maintainer) #26597 (same family: the Studio Access matrix drawing a grant differently from the runtime). Measured once with a failing jsdom probe against the real editor page; the runtime side was read in code.
- The symptoms, the reproduction and the code location are withheld pending maintainer, per the maintainer's instruction for security defects that are not to be disclosed. The implementer receives them privately.
Acceptance (public part)
- For every object grant shape the runtime honours, the matrix shows exactly what the runtime enforces.
- No click writes a change to effective access that the admin did not see on screen.
- A pin covers the case on the display side.
Filing facts
- Business reason: admins decide object access from this screen; it must state the effective grant truthfully.
- Reader who acts: an
os-devimplementer, dispatched directly by this PM session (domain:ui). - Dedupe: semantic search
permission matrix wildcard object row Studio Access unticked clone permission seton objectstack-ai/objectstack → 11 hits; none about this display (nearest: Studio Access pillar: the field-permission editor shows a different edit right for a field with no explicit rule than the runtime enforces, and its bulk controls change edit rights silently (detail withheld pending maintainer) #26597, the field-row sibling; closed Permission matrix (Setup / Studio Access): readScope and writeScope cannot be set or seen, though ADR-0084 declares the record-scope column #26187 readScope column). - Source: out-of-scope finding of the Studio Access pillar: the field-permission editor shows a different edit right for a field with no explicit rule than the runtime enforces, and its bulk controls change edit rights silently (detail withheld pending maintainer) #26597 implementer (PR fix(app-shell): the field-permission editor shows and writes exactly what the runtime enforces for a field with no explicit rule #27006), 2026-10-28, session
session_01J8VVAkZns5rNnK2rtszzbQ.
Metadata
Metadata
Assignees
Labels
area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsPermissions that actually hold — RLS/FLS, sharing model, write-path guardsbugSomething isn't workingSomething isn't workingdomain:uiDomain lane — seat card indexed by label:pm:seatDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3Medium: important, M3security
Activity
objectstack-fleet commentedon Oct 28, 2026
Blocked-by: #26597
Held until PR #27006 (which
Fixes #26597) merges. Both changeui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx, so this card is dispatched serially on the merged code. Maintainer direct dispatch: the authorizing words, verbatim, 「不能公开的安全问题,你直接使用pm-dispatch 派发处理」. Sessionsession_01J8VVAkZns5rNnK2rtszzbQwill claim and dispatch it once #27006 lands.Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Claim: PM loop round 1 (maintainer direct dispatch)
Session:
session_01J8VVAkZns5rNnK2rtszzbQAccount:
huangyiireneBranch:
claude/issue-27010-matrix-object-grant-displayWorktree:
objectstack-issue-27010Domain:
domain:uiSeat:
domain:ui#1(direct-dispatch session, not a lane seat)File surface:
ui/packages/app-shell/src/views/metadata-admin/**(the object rows of the permission matrix, and permission-slice if the drawing helpers live there) (stop on breach; explain in the report)Container & model:
M,mode:subagent,model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate),effort: xhigh(security)Clause-②: no
Metadata-protocol: none
Responsibility: detail withheld pending maintainer |
none| detail withheld pending maintainerThread-read: none
Premise: holds (found 2026-10-28 by the #26597 implementer with a failing probe on the real editor page; Blocked-by #26597 is now cleared, because PR #27006 merged as a90163d)
Serial constraints cleared: #27006 merged (a90163d), so the work starts from it; no other in-flight claim on this directory
Direct-dispatch authority — maintainer, this session, 2026-10-27, verbatim: 「不能公开的安全问题,你直接使用pm-dispatch 派发处理」
Reproduction steps stay off GitHub per that instruction; they go to the implementer in the private dispatch prompt.
Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
os-dev-report
{ "issue": 27010, "status": "done", "branch": "claude/issue-27010-matrix-object-grant-display", "pr": "https://github.com/objectstack-ai/objectstack/pull/27051", "session": "session_01J8VVAkZns5rNnK2rtszzbQ — this run's harness-stamped id (subagent = parent's)", "premise_still_valid": true, "summary": "The permission matrix's object rows (routed page = Setup editor, and the Studio Objects tab) now draw the object entry the runtime applies via one helper (`objectRuleCell` / `objectRuleSeed` in permission-slice.ts), marked inherited in the grey-dashed field-row vocabulary, and every row, scope, shortcut and field edit starts from the drawn entry. 'Only granted', the granted-object count and the delegated-admin companion list read the same resolution; runtime unchanged, its half pinned in plugin-security. Exploit-shaped detail: withheld on GitHub per the maintainer's disclosure rule; the coordinator's copy carries it.", "tests": "ui (vitest from ui/, --maxWorkers=2): the three new files 41/41 passed (exit 0); related set (metadata-admin PermissionMatrixEditor*, permission-slice*, PermissionAdvancedFacets*, previews/PermissionPreview*, previews/adminPreviews.i18n-10862-s2, PositionPermissionSetsSection, studio-design accessTabs-12456, i18n studio-namespace) Test Files 51 passed (51), Tests 429 passed (429), exit 0. plugin-security: `pnpm --filter @objectstack/plugin-security exec vitest run --maxWorkers=2 src/object-grant-wildcard.test.ts` Test Files 1 passed (1), Tests 20 passed (20), exit 0. Type-checks: app-shell type-check (tsc --noEmit + tsconfig.test.json, whose --listFilesOnly carries all three new test files), i18n type-check, plugin-security typecheck incl. check:test-typecheck: exit 0 each. Ablation at 60ed127c (committed fix): `node scripts/ablation-replace.mjs` mutated objectRuleCell's inherited branch (anchor 1 -> 0, blob 8ade369f -> 87539ee9), 25 of 41 new ui cases red, auto-restored (blob == HEAD 8ade369f, git diff HEAD empty); no dist preflight needed — the tests import the module by relative path. Premise run: the two new editor-side files against the three source files restored from a90163d4 (tree only): 23 of 24 red; restored with `git checkout HEAD --` on absolute paths, blobs == HEAD and git diff HEAD empty.", "gates": "local: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (no paths) at d779ee6d derived 66 families for the 10-path change set; all 66 ran, exit codes captured before any pipe. 64 exited 0 on the first run; `pnpm check:dual-build-cjs-loads` and `pnpm check:i18n` exited 3 (PREREQUISITE NOT MET: unbuilt dist), then exited 0 after their prerequisite builds (the closure turbo build check:i18n names; a full-tree `turbo run build` with the root build's filters, 116 tasks, for dual-build). `--ran` over the recorded `CMD :: exit N` list: exit 0, \"66 derived, 66 run, 0 NOT-MEASURED, 0 UNRUN\". ui/package.json gates check:i18n-keys, check:i18n-drift, check:i18n-dead-keys, check:i18n-designer-parity, check:designer-field-key-parity, check:new-line-citations (0 new citations), check:control-bytes: exit 0 each. Local-only families check:dev-prereqs / check:skill-frame-freshness: not owed (no packages/spec build, no four-axis frame file). check-platform-checklist --changed-from: not owed (no exported symbol renamed or deleted; three added). CI: the PR's check-runs at d779ee6d were read once at report time and not waited on: 18 in_progress (Check Changeset, Check PR Size, Flag docs affected by code changes, Governed Surface Queue Guard, Lint · CI release & engine gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, Lint · scoped ×3, PR-body guards, Type Check · consumer gates / debt ledger / source gates / workspace, filter), 2 skipped (18.x upgrade harness (opt-in), Packed-tarball smoke (opt-in)); Test UI, Test Core, Build Core, Lint UI, Type Check UI and Build & E2E UI not yet listed — in_progress, NOT MEASURED here.", "dogfood_battery": "n/a — no `!` in the PR title, and Clause-② is `no` with no (narrowing) arm", "mcp_calls": "0 — no MCP GitHub calls of any kind", "api_writes": "2 strokes through the fleet relay (repository_dispatch, executed as objectstack-fleet[bot]): (1) pr_create — POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos/objectstack-ai/objectstack/issues/27051/assignees, run 40626029609, read-back 8281 bytes sent = stored, assignee huangyiirene; (2) comment — POST /repos/objectstack-ai/objectstack/issues/27010/comments (this report). git push x5 to the feature branch (not REST).", "open_questions": [ { "question": "Product fork (detail withheld on GitHub per the maintainer's disclosure rule; the coordinator's copy carries it): should the matrix gain a control for the entry inherited rows draw from, or a per-row return-to-inheriting action?", "options": [ "A — neither (this PR)", "B — a control for the set-wide entry", "C — a per-row return-to-inheriting action" ], "recommendation": "A — no measured demand, no capability added; reasons on the four axes in the coordinator's copy" } ], "out_of_scope_findings": [ "carrier: none · noted, not filed — surface survey results withheld on GitHub per the maintainer's disclosure rule; the coordinator's copy carries it", "carrier: none · noted in the PR's Acceptance notes, not filed — docs drift in content/docs/permissions/administrator-guide.mdx Step 5 (object-grid bullet lists retired columns, omits Export)" ], "deviations": [ "The claim's file surface named the object rows and permission-slice.ts; the PR also changes PermissionAdvancedFacets.tsx (inside the dispatch's declared ui/packages/app-shell/src/views/metadata-admin/** surface, same defect class, same helper) and adds test-only packages/plugins/plugin-security/src/object-grant-wildcard.test.ts as the dispatch asked.", "origin/main moved 4 commits past a90163d4 during the run (cb8988ee, c79eda5e, 6d9e5a18, b3f73445); none touches a file in the diff, so the branch was not merged; the queue tests the combined tree.", "The GitHub copy of this report is redacted per the maintainer's disclosure rule (summary, the premise detail, open_questions detail and out_of_scope_findings); the coordinator's copy (the final message) carries them. Same keys in both." ] }Generated by Claude Code
test(app-shell): give #27010's and #26837's matrix doubles the draft-…