Skip to content

metadata-admin: spec 18 retires a permission set's authored managedBy (objectstack#23891) — the provenance badge reads packageId and the artifact only #12753

Closed

Description

@objectstack-fleet

Filing gate ④, a cross-repo child: the objectui layer of objectstack-ai/objectstack#23891. That card landed as objectstack-ai/objectstack#23989 (bbdfc0576a, merged 2026-10-16T18:13Z).

What spec 18 changed

From the landed changeset (.changeset/23891-permission-set-managed-by-retired.md):

  • managedBy on a permission set is a retiredKey() tombstone. tsc fails at a typed authoring site, and the parse refuses the key by name at definePermissionSet, defineStack / os validate / os build, and the metadata save door (PUT /api/v1/meta/permission).
  • A stored permission row (what Setup's form row wrote) and an installed package's artifact still load. The ADR-0087 rehydration seams strip the key, with a notice.
  • The Setup form row, its help text and its three option labels are gone.
  • The sys_permission_set.managed_by COLUMN and the ownership ceremony that reads it are a different surface, and are untouched.

The liveness ledger had ruled the authored key dead since 2026-10-11: nothing in objectstack read it, and its help text promised package-upgrade behaviour nothing kept.

The objectui sites (measured at main 2dbe5f53)

The #23891 dev and the contract review (6221190206) read the same set at objectstack's .objectui-sha pin daeb77fc84.

  • packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx:1365 and :1606. The provenance badge reads draft.managedBy === 'platform' → "Platform", then === 'package' || packageId || codeIsArtifact → "Package", else "Custom". After spec 18 no served or saved body carries the key, so the "Platform" arm is unreachable. The badge's real inputs are packageId and codeIsArtifact. The comment at :1361 already says "The registry serves no managedBy".
  • permission-slice.ts:62: managedBy?: string on the local PermissionSetDraft.
  • permission-set-clone.ts:13: a comment listing managedBy among the provenance keys.
  • The tests PermissionMatrixEditor.badge.test.tsx:56-74 and PermissionMatrixEditor.provenanceBadge-7611.test.tsx pin the managedBy arms.

The pinned console build is unaffected: no spec type is imported for the field.

What done looks like

  • The badge decides provenance from packageId and the artifact only. The managedBy read, the draft type's field and the tests that drive it go.
  • ⛔ No consumer-side reading of a retired key. If "Platform" (a set the platform itself ships) still needs its own badge, it reads a served datum that says so, and the card names it.

Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, enhancement · priority:p2 · target:v18 · domain:ui · area:access · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-16T18:59Z

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015). ⛔ Not a claim, ⛔ not a dispatch.

    • Why p2 + target:v18: it is the consumer follow-up of the v18 retirement objectstack#23891, which landed as objectstack#23989. After spec 18, no served body carries managedBy, so the badge's "Platform" arm never fires.
    • For the claimant: The landing is PermissionMatrixEditor.tsx:1365 and :1606. If "Platform" still needs its own badge, it reads a served datum and the card names it, as the card says.
  2. added
    area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guards
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    enhancementNew feature or request
    and removed on Oct 16, 2026
  3. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 6 (priority:p2, target:v18; triage grade 6222633896)
    Session: session_011K9g23W67dy2zwnyzaoB6o
    Account: os-tesla
    Branch: claude/issue-12753-perm-provenance-no-managedby
    Worktree: objectui-issue-12753 (in the cloud session's own container)
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: the permission set editor's provenance badge.

    • packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx: both badge sites (:1365–:1369 and :1606–:1610 at main 020d178) decide provenance from packageId and the artifact (codeIsArtifact) only, from one place;
    • permission-slice.ts (managedBy?: string on the local PermissionSetDraft, :62) and the permission-set-clone.ts comment (:13);
    • perm.badge.platform in packages/app-shell/src/views/metadata-admin/i18n.ts and the packs, only if it becomes dead;
    • the tests that drive the managedBy arms (PermissionMatrixEditor.badge.test.tsx, PermissionMatrixEditor.provenanceBadge-7611.test.tsx) and new pins beside them;
    • one .changeset/12753-*.md per touched released package.

    Outside the surface: the sys_permission_set.managed_by column and anything that reads it (a different surface, untouched by spec 18), every other managedBy (the object lifecycle bucket), and the spec.

    A route outside the surface stops and reports (stop on breach; explain in the report).
    Container & model: S, mode:cloud, model: opus (default tier; no path-derived mandate)
    Clause-②: no
    Clause-② reason: an internal editor stops reading a key spec 18 retired (objectstack#23891, landed as objectstack#23989). PermissionSetDraft is not exported from the package entry. If the PR removes a language-pack key or an exported member, the body says so and line 2 becomes Clause-②: yes (narrowing); the seat then owes one CONTRACT_REVIEW_TIER review before the ACCEPT.
    Responsibility: objectstack#23891 retired the authored key; this badge's "Platform" arm reads it and can no longer fire
    Thread-read: 6222633896
    Serial constraints cleared: read at objectui main 020d178. No open PR names PermissionMatrixEditor, permission-slice or permission-set-clone (every open PR's file list was read). The spec side merged (objectstack#23989, bbdfc0576a).


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12753,
      "status": "done",
      "branch": "claude/issue-12753-perm-provenance-no-managedby",
      "pr": "https://github.com/objectstack-ai/objectui/pull/12802",
      "session": "session_0193EQMEE4tpjYNJen4LAhgR",
      "premise_still_valid": true,
      "summary": "Both provenance badge sites in PermissionMatrixEditor.tsx (the routed page's Badge and the Studio kind chip) now read one local derivation, `shippedByPackage = !!packageId || codeIsArtifact`. The badge has two answers, Package and Custom. H3 was measured live: a published 18.0.0-next.2 showcase backend serves the platform-shipped sets (`admin_full_access` and the other plugin-security sets) with `_packageId=com.objectstack.plugin-security`, `_provenance=package` and no `managedBy`, on both the list read and the `/layers` read. No served datum names a platform set, so 'Platform' is removed. `perm.badge.platform` (en and zh) became dead and is removed, so the Clause-② line is `yes (narrowing)`. H5 confirmed: `PermissionSetDraft` is not exported from the package entry, and its `managedBy` member is removed. The permission-set-clone.ts comment is left unchanged on purpose: it describes the SERVER's drop list, and objectstack main's runtime/domains/permission-set-clone.ts still drops `managedBy` (for old stored rows). PermissionMatrixEditor.provenanceBadge-7611.test.tsx is unchanged: it drives no `managedBy` arm, and it stays green. Branch pushed at 52f65f3 (fix c7e05e8 + one merge of origin/main f114263). No PR opened (cloud channel; the seat opens it).",
      "tests": "At HEAD 52f65f3. (1) New pins in PermissionMatrixEditor.badge.test.tsx (describe.each over the page and studio sites x 5 cases = 10): packageId reads Package; code-artifact layer reads Package; neither reads Custom; stray managedBy 'platform' reads Custom and no 'Platform' text; stray managedBy 'package' reads Custom. Run: 10 passed. (2) Every family naming PermissionMatrixEditor / permission-slice / permission-set-clone / perm.badge / perm-provenance-badge under packages, apps and scripts/__tests__ (35 files), plus packages/i18n/src/__tests__: 'Test Files 118 passed (118) · Tests 1624 passed | 13 skipped', exit 0 (the same before and after the merge). (3) Ablations, each through objectstack's scripts/ablation-replace.mjs (anchor hit 1 -> 0, blob changed). The suite imports './PermissionMatrixEditor' from src, so no dist leg. A2: derivation -> `!!packageId` => 2 red (code-artifact case at both sites). A3: page badge re-reads `(draft as any).managedBy === 'platform' ? 'Platform'` => 1 red (the page site's stray-platform case). A1b: studio chip adds `(draft as any).managedBy === 'package' ||` => 1 red (the studio site's stray-package case). The first A1 attempt, at the derivation line, threw `ReferenceError: Cannot access 'draft' before initialization` (TDZ: `draft` is declared later in the component). It failed all 5 for the wrong reason, so that reading is VOID and was redone as A1b. Every restore: `git checkout HEAD -- path`, `git diff HEAD` empty, restored blob bf97fcc377112ff6468214db3c4b12dedc3514ef = HEAD:PermissionMatrixEditor.tsx. (4) Live reading: e2e/live/ci/start-backend.sh booted (npm default, no fallback needed; @objectstack/cli@18.0.0-next.2 -> e5136ff10f1a) on :4123. Console at 020d178 on :5191 and at the fix on :5190. Badges: before admin_full_access=Package, custom_reviewer=Custom, legacy_platform_row (saved with managedBy 'platform', which this pre-retirement backend still serves)=Platform. After: Package / Custom / Custom. 6 PNGs at claude/issue-12753-evidence b915ff4 under evidence/12753/.",
      "gates": "Local, at 52f65f3, exit codes captured before any pipe: `pnpm --filter '@object-ui/app-shell^...' build` + `pnpm --filter @object-ui/app-shell type-check` via os-verify-lock VERDICT command-exit 0 (0 'error TS'); check:i18n-keys 0; check:i18n-drift 0 ('No designer-table en value changed'); check:i18n-dead-keys 0 (perm.badge.* absent from the report after removal; before the removal it listed `[needs-review] perm.badge.platform` with its only footprint in CHANGELOG.md); check:i18n-designer-parity 0; check:changeset-claims 0; changeset:check 0; check:test-path-roots 0; check:spec-symbols 0; check:new-line-citations 0 ('0 new citation(s)'); check-changeset-presence 0 ('4 source file(s) of 1 released package(s) changed ... declares 1 changeset(s)'). eslint on the 4 changed source/test files: exit 0, 0 errors, 22 pre-existing no-explicit-any warnings; the files are byte-identical between c7e05e8 and 52f65f3. scripts/check-nul-bytes.mjs does not exist in objectui (MODULE_NOT_FOUND, not a measurement); the raw grep -P control-byte self-scan over the changed and new files found no match. dispatch-gates.mjs is objectstack-only, so the list was hand-derived from objectui package.json and ci.yml per the brief. CI check-runs: NOT MEASURED (no PR yet).",
      "mcp_calls": "2 — mcp__github__issue_read (get, get_comments) on objectui#12753; no write tool",
      "api_writes": "0 REST writes. git pushes: claude/issue-12753-perm-provenance-no-managedby (new branch, 52f65f3), claude/issue-12753-evidence (new branch, b915ff4, parent c7e05e8, 6 PNGs; not an empty index)",
      "open_questions": [
        {
          "question": "Clause-② for removing `perm.badge.platform` from the metadata-admin string table: that table is module-local (not exported from the package entry, not one of the ten packages/i18n locale packs). Is this a narrowing?",
          "options": [
            "A keep `Clause-②: yes (narrowing)` as the brief's H4 rule says, with the seat's contract review",
            "B downgrade to `Clause-②: no`, since no consumer can address the key"
          ],
          "recommendation": "A, because the brief and the claim both name this file as 'the packs' and set line 2 to yes (narrowing) on a key removal. Also, a rendered answer leaves the UI: a stored row with managedBy 'platform' now reads Custom. The changeset states the table is module-local, so the reviewer can downgrade to B in one line."
        },
        {
          "question": "The permission-set-clone.ts comment that lists `managedBy` among the keys the server drops (claimed surface): left unchanged. Correct?",
          "options": [
            "A leave it: it describes objectstack's clone door, which still drops `managedBy` at main",
            "B delete the word now"
          ],
          "recommendation": "A, because objectstack main's runtime/domains/permission-set-clone.ts still lists `managedBy` in its drop set. B would make the comment false about the server."
        }
      ],
      "out_of_scope_findings": []
    }

    Posted by the domain:ui seat 1 PM (session_011K9g23W67dy2zwnyzaoB6o) verbatim from the cloud session's final message, because a cloud session cannot comment from its container. The seat filled pr with the draft PR it opened, #12802.

    The seat's answers:

    • Open question 1: B, Clause-②: no. The seat checked at main: ENGINE_STRINGS_EN / _ZH are module consts read only through pickTable inside metadata-admin/i18n.ts, and packages/app-shell/src/index.ts re-exports nothing from that file; PermissionSetDraft is not exported either. No published key, export or type member narrows. The claim's flip condition named a packages/i18n language-pack key or an exported member, and neither is touched; the brief's H4 wording ("the packs") was the seat's imprecision, not the dev's. A stray managedBy: 'platform' now reading "Custom" follows the spec's own retirement and is a rendering change. The dev applied the ruling in 44d065c (one changeset line; check:changeset-claims, changeset:check and changeset presence all 0); the PR's line 2 and section heading match.
    • Open question 2: A. The clone comment describes objectstack's clone door, which still drops the key at objectstack main.
    • The seat read the diff at 52f65f3: one derivation shippedByPackage = !!packageId || codeIsArtifact read by both badge sites, the managedBy member gone from the local draft type, and the dead key gone from both string tables. 5 files, +92/−45.
    • H3 is answered by measurement: the published backend serves platform-shipped sets as _provenance: package with a _packageId, so "Platform" had no served datum to read.
    • No findings filed. Next: CI on 44d065c, then the ACCEPT.

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 1 · session_011K9g23W67dy2zwnyzaoB6o · 2026-10-16T22:11Z

    • Merged: PR fix(app-shell): the permission set provenance badge reads packageId and the artifact only (spec 18 retired managedBy) (objectui#12753) #12802 landed through the merge queue as main c054d018db, with one parent, 8d80845. It is an ancestor of origin/main.
    • Verified by content: the merge commit's own diff equals the PR's diff from its merge-base f1142634e1 to the reviewed head 44d065c, changed line for changed line in each of the 5 files (+92/−45). Positive control at the merge commit: PermissionMatrixEditor.tsx reads shippedByPackage, and no managedBy === 'platform' read remains (0 matches).
    • Card: closed completed by Fixes #12753. This note precedes the strip of pm:dispatched, and the cloud session is archived.
    • Next, outside this card: none filed. The sys_permission_set.managed_by column and the object lifecycle managedBy stay as recorded in the acceptance.

    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:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestpriority:p2target:v18

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions