You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
PermissionMatrixEditor does not model the artifact-backed write tier that ResourceEditPage does — an env-scope edit of a code-declared permission set can offer Save and get 403 #4518
Filed unassigned and ungraded while implementing #4446 — routing/grading is the triage seat's call, not the filer's. Independent of #4446 (which is correct as it stands); no Blocked-by:.
Placeholders below are written {set} / {pkg} rather than in angle brackets: GitHub's body sanitizer strips an angle bracket followed by a letter as an HTML tag at rest, which silently ate them on the first save of this issue.
What was measured
The server's metadata write gate is two tiers, not one. From packages/metadata-protocol/src/protocol.ts (objectstack, 5d24f4b94):
Type tier — refuse only when BOTH flags are false:
if(!overlayAllowed&&!runtimeCreateAllowed){ ... }
Artifact tier — for an item that IS artifact-backed, allowRuntimeCreate is not enough:
if(this.environmentId!==undefined){constartifactBacked=this.isArtifactBacked(request.type,request.name);if(artifactBacked&&!overlayAllowed){// [not_overridable] ... provided by a code package// and the type has not opted into per-org overlay writes// status 403}}
The method doc states the split directly: distinguish "overlaying a packaged item" (requires allowOrgOverride) from "authoring a DB-only item" (requires only allowRuntimeCreate).
ResourceEditPage.tsx:1332 models both tiers, including the sys_metadata provenance sentinel that keeps a published org item editable:
PermissionMatrixEditor.tsx models only the type tier. It already loads the layered envelope (client.layered() returns code / overlay / overlayScope) but never reads code for a writability decision.
Why this is not a defect in #4446, and where it could bite
Two of the three surfaces are already covered by something else:
Studio Access pillar — the pillar passes the package-level readOnly prop for a read-only (code-defined) package, which dominates every type flag. Locked, correctly.
The uncovered one is the metadata-admin route at environment scope on a multi-environment kernel: no readOnly prop is passed there, and after #4446 the type tier alone says writable for permission (allowOrgOverride: false, allowRuntimeCreate: true). For a code-declared, artifact-backed set the artifact tier then refuses the save with 403 not_overridable. Result: live checkboxes and a Save button that fails at the end instead of a surface that explains itself up front.
Pre-#4446 this state was unreachable only by accident — the surface was locked for the wrong reason (the overlay flag), so the artifact tier never got a chance to matter.
The #4446 ruling scoped that card to the type-tier disjunction and said explicitly: trust the directory entry's flags exactly as the sibling sites do, do not invent a new server probe. Adding artifact awareness there would also have made the card's own headline case (a code-declared set on the showcase, measured 200) render read-only again — the opposite of what was asked for. So it is recorded here rather than folded in silently.
Suggested direction
Mirror ResourceEditPage's three-way rule in PermissionMatrixEditor, including the sys_metadata sentinel, but keep it scoped to the environment-scope path — under a packageId the write is a package-door draft (ADR-0086 P0/P2) and the measured behaviour there is 200. Worth confirming first whether an artifact-backed permission set is reachable at env scope in the metadata-admin route in practice, since that decides whether this is a real user path or a latent one.
Source
Found while implementing #4446 (PR #4519). Server behaviour read on objectstack 5d24f4b94; client sites on objectui 5cc847c31.
Ruling (delegated authority; open veto window): model the ARTIFACT tier in the permission-matrix editor the way ResourceEditPage:1332 already does — both tiers, including the sys_metadata sentinel — so an env-scope edit of a code-declared permission set on a multi-environment kernel stops offering a Save that 403s. The binding constraint from the filing: the artifact-tier gate is environmentId !== undefined-scoped server-side (protocol.ts:8890-8899) — the fix must NOT re-lock the single-env/showcase case #4519 just opened (that case measured 200 and stays writable). Mirror the sibling's model; do not invent a probe.
Red-first: multi-env shape (environmentId set), artifact-backed permission set, overlay disallowed → pre-fix Save offered (capture) and the write path would 403; post-fix read-only with an honest caption naming the artifact tier. Must-not-change (green both sides): the #4519 headline case (no environmentId — host config boots without one) stays editable; runtime-created sets stay editable on both shapes; the #4519 pin suites all stay green.
Sequencing gate: PR #4519 in origin/main first (armed, CI green — poll ~180s, ≤40min; report BLOCKED otherwise). Same file surface — no parallel edit.
Grading: patch @object-ui/app-shell (.d.ts measured both ways). Never major.
Surface (mutual exclusion): packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx + its pin suites + i18n rows if captions change + one changeset. ⛔ NOT: ResourceEditPage (the correct sibling — read-only reference), protocol/server code, console/**, content/docs/releases/. Disjoint from in-flight #4252/#4213/#4513/#4503r.
Activity
yinlianghui commentedon Aug 13, 2026
CLAIM — session
session_017Qqyix2QcnpUC9XeYVDzx3, branchclaude/issue-4518-matrix-artifact-tier.Ruling (delegated authority; open veto window): model the ARTIFACT tier in the permission-matrix editor the way
ResourceEditPage:1332already does — both tiers, including thesys_metadatasentinel — so an env-scope edit of a code-declared permission set on a multi-environment kernel stops offering a Save that 403s. The binding constraint from the filing: the artifact-tier gate isenvironmentId !== undefined-scoped server-side (protocol.ts:8890-8899) — the fix must NOT re-lock the single-env/showcase case #4519 just opened (that case measured 200 and stays writable). Mirror the sibling's model; do not invent a probe.Red-first: multi-env shape (environmentId set), artifact-backed permission set, overlay disallowed → pre-fix Save offered (capture) and the write path would 403; post-fix read-only with an honest caption naming the artifact tier. Must-not-change (green both sides): the #4519 headline case (no environmentId — host config boots without one) stays editable; runtime-created sets stay editable on both shapes; the #4519 pin suites all stay green.
Sequencing gate: PR #4519 in
origin/mainfirst (armed, CI green — poll ~180s, ≤40min; report BLOCKED otherwise). Same file surface — no parallel edit.Grading: patch
@object-ui/app-shell(.d.tsmeasured both ways). Never major.Surface (mutual exclusion):
packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx+ its pin suites + i18n rows if captions change + one changeset. ⛔ NOT:ResourceEditPage(the correct sibling — read-only reference), protocol/server code, console/**,content/docs/releases/. Disjoint from in-flight #4252/#4213/#4513/#4503r.Generated by Claude Code
Generated by Claude Code
fix(app-shell): the permission matrix models the artifact tier — no S…