Repository navigation
feat(fields,app-shell): the capability select lists the capability registry; the matrix badge reads the layered envelope (part of objectui#7611) - #12153
Conversation
…gistry; the matrix badge reads the layered envelope (part of objectui#7611) CapabilityMultiSelectField now lists the console metadata store's `capability` items (GET /api/v1/meta/capability: the curated platform capabilities beside every package-declared one), read through `MetadataCtx` `ensureType` as RecipientPickerField reads the position registry. It no longer asks a data source for `sys_capability` rows, which nothing writes any more, so on a fresh database it offered only the set's own selections. No second source is merged in; the union with the set's own selections stays so a granted name is never hidden. PermissionMatrixEditor's identity badge reads "Package" off the same layered-envelope verdict its artifact gate reads (`codeIsArtifact`), so a set a code package ships no longer reads "Custom" beside its lock at the environment scope. Claude-Session: https://claude.ai/code/session_01Rerax7QTjKMPCUZxQUtPFR Co-authored-by: Claude <noreply@anthropic.com>
…pe's registry list; pin it read-only with no switch (part of objectui#7611) Measured on a fresh showcase: `…/metadata/capability?scope=environment` lists the capability registry (the curated platform capabilities beside the package-declared ones) read-only, with no create affordance and no active switch, and reads no `sys_capability` row. No code change is needed for it. SETUP_CATALOG_TYPES keeps `capability` out on purpose: it names the types with an activation switch, and the activation door refuses a capability. Its docblock and the app-shell README said the page still read `sys_capability` rows; they now say what it serves. The changeset covers the capability select and the provenance badge. Claude-Session: https://claude.ai/code/session_01Rerax7QTjKMPCUZxQUtPFR Co-authored-by: Claude <noreply@anthropic.com>
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Part of #7611
Clause-②: no
PR-1 of the objectui#7611 remainder, as the seat's claim amendment on objectui#7611 (comment 6111342697) dispatched it: census item 1 (the capability select), census row 1b (the Capabilities catalog page) and F2 (the permission-set editor's "Custom" badge). objectui#7611 stays open: items 3, 4 and 5 and row 8c are other PRs.
Clause-② is
no: no export is added or removed and no exported type changes.CapabilityMultiSelectFieldkeeps its props type; what changes is where its options come from (below), and it no longer reads thedataSourceprop.What changed
Item 1: the capability select lists the capability registry.
CapabilityMultiSelectField(@object-ui/fields) reads thecapabilityitems of the console metadata store (MetadataCtxensureType, which isGET /api/v1/meta/capability). That is the readerRecipientPickerFieldalready uses for thepositionregistry; there is no object-name special case. It no longer callsdataSource.findonsys_capability. No second list is merged in; the existing union with the set's own selections stays, so a granted name the registry does not serve is still shown, selected, under "Other". The grouping by scope and the curated client-side labels are unchanged. Without a metadata store the picker offers the set's own selections and loads nothing (no endless "Loading capabilities…" line). The host,PermissionMatrixEditor, no longer passes the adapter to it. The ten locale packs' comments that said the labels come from "the sys_capability registry" now say "the capability registry".Row 1b: the Capabilities catalog page. Measured in a browser (below):
/apps/setup/metadata/capability?scope=environmentalready renders the capability registry read-only, with no code change. It lists all 11 items, with no "New" button, no active switch, no status filter and nosys_capabilityread, and an item opens locked with no Save. So the change is documentation only.SETUP_CATALOG_TYPESkeepscapabilityout ON PURPOSE: the constant names the types with an activation switch (hasCatalogActivationreads it), and the activation door refuses a capability. Adding it, the "smallest change" the census named, would put a switch on that page that every click refuses. The ablation below shows that. Its docblock and the app-shell README said the page "still readssys_capabilityrows"; they now say what it serves.The URL for objectstack's stage 8:
nav_capabilitiesshould point at/apps/setup/metadata/capability?scope=environment, the same scope-carrying formSystemCatalogRedirectuses for positions and permission sets. objectstack's nav is not changed here.F2: the provenance badge. The identity strip's badge now also reads
codeIsArtifact, the layered-envelope verdict the artifact lock already reads. A set a code package ships reads "Package" beside its "Read-only (this set is provided by a code package)" lock. Before this change it read "Custom", because the registry serves nomanagedByand the environment scope passes nopackageId. The badge gainsdata-testid="perm-provenance-badge".Measured on a fresh showcase
objectstack
origin/main8532783f65 (objectstack dev --seed-admin --fresh, showcase), with this branch's console served by vite against it, signed in as the seeded admin. Before = the two changed source files at the base commit a7d4920 (the A1 mutation below); after = this branch.GET /api/v1/meta/capabilitylists 11 items: the 9 curatedPLATFORM_CAPABILITIES(_packageIdcom.objectstack.plugin-security) and 2 that the showcase package declares (showcase.export_data,showcase.restricted_ops).GET /api/v1/data/sys_capabilityanswerstotal: 0; the controlGET /api/v1/data/sys_useranswers rows.setup.access. Before: one chip, "Setup Access", under "Other". The request wasGET /api/v1/data/sys_capability?top=500&filter=…active…. After: 11 chips. Platform: Manage Metadata, Manage Platform Settings, Manage Users, Setup Access (on), Studio Access. Organization: Export Showcase Data, Manage Organization Users, Manage Sharing, Restricted Showcase Operations, View All Audit Log, Write Settings. The one capability request wasGET /api/v1/meta/capability.showcase_opsandadmin_full_accessat the environment scope. Before: "Custom" beside the lock. After: "Package" beside the lock. The environment-authored probe set reads "Custom" both times.Tests
New and updated pins, each red against an ablation, with the restore proven on disk:
CapabilityMultiSelectField.test.tsx— a new describe block, "the options are the capability registry (objectui#7611)", with three cases: it lists the registry items, curated and package-declared, and never asks a handed-in data source for rows; it adds a package-declared capability by name; with no store, it offers only the selections and does not sit on the loading line. The file's existing cases andCapabilityMultiSelectField.specParity-6285.test.tsxnow feed the registry through a store instead of a mockedsys_capabilitydata source.PermissionMatrixEditor.provenanceBadge-7611.test.tsx(new) — a code-package set reads "Package" beside its lock. Three controls still read "Custom": no code layer, an organization-authored set with a code-looking_packageId, and thesys_metadatasentinel.ResourceListPage.environmentScope-7611.test.tsx— a new describe block for the Capabilities page: every registry item is listed with the scope kept; no create, no status filter and no switch; no request to the ledger or tosys_capability.Ablations, one per pin, each run from a committed state:
CapabilityMultiSelectField.tsxset back to its base blob (git checkoutof a7d4920, unstaged; on disk the registry read counts 0 and the row read 1, and the blob equals the base blob). Result: 9 failed, 11 passed, including all three new registry cases. Restored withgit checkout HEAD --on the absolute path; the blob equals HEAD andgit diff HEADis empty.scripts/ablation-replace.mjsdeleting|| codeIsArtifactfrom the badge (anchor 1 → 0). Result: 1 failed (Expected "Package", Received "Custom"), and the 3 controls passed. Restored; the blob equals HEAD andgit diff HEADis empty. A first attempt replaced the condition with a substring of itself; the tool refused it before running anything because the replacement count did not rise, so that attempt was a no-op.scripts/ablation-replace.mjsadding'capability'toSETUP_CATALOG_TYPES. Result: the 1b case failed (the status filter rendered) and the other 11 passed. Restored the same way.Local verification at
0070a807eEvery run below was on HEAD
0070a807e, the branch's last commit. Builds and tests went through the shared verify lock. The verdict quoted is the one each tool printed.pnpm exec vitest run packages/fields/— 244 files passed and 1 skipped; 3979 tests passed and 7 skipped.pnpm exec vitest run packages/app-shell/src/views/metadata-admin/plus the 16 test files outside that directory that name a touched module (found withgit grep; console, studio-design, plugin-detail, data-objectstack, schema-catalog and fields) — 488 files passed; 5512 tests passed and 1 skipped.pnpm exec vitest run packages/i18n/— 82 files passed; 1316 tests passed and 13 skipped.pnpm turbo run build --filter='@object-ui/app-shell^...'— 28 of 28 tasks succeeded. It ran first so that the type checks read freshly built typings.pnpm --filter @object-ui/fields type-check,@object-ui/i18nand@object-ui/app-shell— each exited 0.tsc -p tsconfig.test.json --listFilesOnlylists the new and changed test files in both packages.--no-inline-configon the 17 changed TS files (counted from--format json): 0 errors. Type-aware linting is not configured (eslint.config.jssets noparserOptions.projectorprojectService), so this diff cannot move a verdict on an untouched file. Repo-widepnpm lintis CI's.check:new-line-citations(0 new),check:control-bytes,check:i18n-keys,check:i18n-drift,check:vi-mock-specifiers,check:vi-mock-inherit,check:vi-mock-override-shape,check:test-path-roots,check:changeset-claims,check:pending-changeset-literals,check:unused-depsandcheck:phantom-deps.check-governed-queue-guard --teston the 19 paths: NOT GOVERNED.check:readme-exports. Its prerequisite was not met: it needs every package'sdisttypings, and it refused with "the population COLLAPSED" (36 of 40 packages unbuilt). This PR touches only prose in a README, not a code fence. CI builds and runs it.Narrowed, and declared as narrowed: the app-shell package's own suite was not run whole. CI runs it.
Acceptance notes
sys_capabilityrows. The changeset says so. The objectui#7611 line targets the v18 framework, where the registry serves all of them.Generated by Claude Code