Skip to content

Commit 73c7dc4

Browse files
fix(spec): PermissionSet.description liveness cites its live reader, Studio's permission-set list column (#23467)
Fixes #23404 Clause-②: no ## What this changes The liveness ledger had `PermissionSet.description` as `live`, but its evidence named two readers that no longer exist: `sys-permission-set.object.ts` (removed at C3 stage 8) and `permission-set-projection.ts` (removed at stage 7a). This PR re-checked whether the key still has a reader, as the card asked (measurement first). It does, in objectui. Studio's permission-set list shows the authored `description` as a column. The `description` row in `packages/spec/liveness/permission.json` now cites that reader, so the status stays `live`. `verifiedAt` moves to 2026-10-14, `evidenceScope` is `cross-repo`, and the note records the re-check. The `label` row next to it had the same stale evidence (the record title of the sys_permission_set row object, retired at C3 stage 8). It now cites the same reader, the `label` list column at builtinComponents.tsx:206, with the same ResourceListPage.tsx:698 and getMetaItems citations, `evidenceScope: cross-repo` and `verifiedAt` 2026-10-14. No other row changes. *(Added by the seat at its review: the claim was amended to take the `label` row.)* A patch changeset (`.changeset/23404-permission-set-description-liveness.md`) comes with it, because `liveness/` is in `@objectstack/spec`'s `files[]` and ships in the package. ## The measurement **Where the reader is** (objectui; read through `git` at the `.objectui-sha` pin `b9814b334d8a` and at objectui `main` `524136ea7`, identical at both): - `packages/app-shell/src/services/builtinComponents.tsx:194-208` registers the `permission` metadata resource with `listColumns` `name`, `label`, `description`. - `packages/app-shell/src/views/metadata-admin/ResourceListPage.tsx:329` gets the rows through `client.list(type)`, which is `GET /api/v1/meta/permission` (`packages/data-objectstack/src/metadata-client.ts#list`). Line 698 renders `row.item[c.key]` for each column through `defaultCell`. The page is mounted at `metadata/:type` (`packages/app-shell/src/console/AppContent.tsx:1014`). - The other `permission` registration (`anchors.ts:373`) sets no `listColumns`, and `registerMetadataResource` merges a later registration into the earlier one, so the column stays. `resolveResourceConfig` does not change the columns either. - On the framework side, `packages/metadata-protocol/src/protocol.ts#getMetaItems` serves the flattened authored body without projecting it. The only built-in redactor is for `datasource` (`packages/spec/src/kernel/metadata-type-redaction.ts`), so the authored `description` reaches the column. - The README's display/behaviour table says that for a display-only key, being shown to a human is the whole of the claimed effect. So this reader is enough for `live`. **Where else I searched, and why those hits are not readers** (objectstack `origin/main` `7b3d5585c`): - `git grep` for `(ps|set|permissionSet|…)?.description` across every package `src` returned three hits: - `packages/core/src/security/permission-set-row-definition.ts:105` turns a legacy `sys_permission_set` row INTO the key, for the `os migrate` ceremony. That makes it a producer, not a reader. - The other two (`email-template-row-definition.ts`, `position-row-definition.ts`) belong to other types. - `packages/plugins/plugin-security/src`: every `description` hit is a producer (the built-in sets in `default-permission-sets.ts` author it), object-field metadata, or a comment. The security catalog never reads the key. - `packages/rest/src` and `packages/metadata/src`: the hits project other things (docs trees, type entries), not a permission set's body. - i18n (`spec/src/system/i18n-resolver.ts`, `cli/src/utils/i18n-extract.ts`) and the CLI `explain`: nothing about permission sets. - MCP/AI tools: no tool lists permission sets with their description. - The console bundle is not in this repo (`packages/console` tracks no `dist/`). - objectui `@object-ui/types`: no `PermissionSet` type. - objectui `PermissionMatrixEditor.tsx` (the edit page): no `description` read. `PermissionPreview.tsx:118` reads an RLS policy's `description`, not the set's. **Positive control:** the same search, run for `label`, finds its reader in the same place: the same `listColumns` entry, rendered by the same `ResourceListPage.tsx:698`. **Negative control:** `managedBy`, which the ledger records as `dead`, has no column there. The comment at `builtinComponents.tsx:200-203` says it was removed on purpose. ## Verification - `pnpm --filter @objectstack/spec run check:liveness`: green on the final tree. The run includes "every `path#symbol` anchor names a symbol its file contains, and every cited file names the property it is evidence for". - **Two ablations, both run through `scripts/ablation-replace.mjs`, which confirmed each mutation was written to disk and restored the file byte-identical to `HEAD` (`git diff HEAD` empty, blob `11c4ba2944a2`):** - Renaming the cited path to `protocolAblated.ts` turns the gate red with `1 'live' … entr(ies) cite a file that is missing from THIS repo`. - Renaming the anchor to `#getMetaItemz` turns it red with `permission/description → packages/metadata-protocol/src/protocol.ts#getMetaItemz` under "anchored citation(s) name a symbol the cited file does not contain". - So the new framework-side citation is one the gate actually checks. The old basenames were not: they read as prose. - A first anchor attempt was a no-op: the replacement text contained the anchor, so the tool refused to run it. It was redone with the replacement above. - `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 60 commands. All 60 ran, and `--ran` reconciles them: 58 run, 2 NOT MEASURED. - `pnpm check:dual-build-cjs-loads` and `pnpm check:lean-entry-closure` exited 3 (PREREQUISITE NOT MET). They need a full-workspace `dist/`, and only `@objectstack/spec` was built here. Left to CI. - `pnpm check:platform-checklist` is red, on stale `#symbol` anchors in `docs/qa/platform-checklist/areas/{access-security,attachments-storage,search}.json` that point at `protocol.ts` and `attachment-access-hooks.ts`. This diff touches none of those files: `git diff 7b3d558 -- docs packages/metadata-protocol packages/services` is empty. It is not caused by this PR. - Every other derived command exited 0. - `pnpm --filter @objectstack/spec run test:repo` (pre-merge head `bd9f64e90`): `Test Files 60 passed (60)` · `Tests 1029 passed (1029)`, lock verdict `command-exit 0`. - After merging `origin/main` `8d5b7bb94` (head `0707d4a5d`): `check:liveness` exit 0 (both ✓ lines), `check:nul-bytes` exit 0, and `check:platform-checklist` still exit 1 with the same 8 problems, which places that red on `main`, not on this diff. - Patch round 1, head `0303ba5c9`: `check:liveness` exit 0. All 60 derived commands ran: 58 measured, 2 NOT MEASURED (exit 3). The platform-checklist red is unchanged and is on main. ## Acceptance notes - `evidence.mts` treats a path that is not rooted at `packages/…` (or another top-level directory) as prose. This is by design and documented in its own header and the README. So a `live` row whose evidence names only basenames is never checked. A walk over the ledger found 99 of 446 `live` rows with no path the gate can resolve (local or foreign), and `permission/label` was one of them before this PR. --- _Generated by [Claude Code](https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 1baf976 commit 73c7dc4

2 files changed

Lines changed: 18 additions & 6 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
The `PermissionSet.description` liveness row cites its real reader again: Studio's permission-set list renders the authored `description` as a column, read off `GET /api/v1/meta/permission`
6+
7+
Clause-②: no (the ledger row's evidence is rewritten and its status stays `live`: `PermissionSetSchema` accepts `description` exactly as before, and no state count moves)
8+
9+
- `liveness/permission.json`: the `description` row's evidence named two readers that are gone, the `sys_permission_set` row object and the permission-set projection. It now cites objectui's `permission` metadata resource, whose list declares a `description` column, and the generic metadata list page that renders it. It also cites the metadata door that serves the authored body to that page. `verifiedAt` moves to 2026-10-14, and the row is marked `evidenceScope: cross-repo`.
10+
- `liveness/permission.json`: the `label` row's evidence named the record title of the `sys_permission_set` row object, which is gone. It now cites the same `permission` metadata resource's `label` list column, the same list page and the same metadata door. `verifiedAt` moves to 2026-10-14, and the row is marked `evidenceScope: cross-repo`. Its status stays `live`.

‎packages/spec/liveness/permission.json‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,17 @@
1010
},
1111
"label": {
1212
"status": "live",
13-
"verifiedAt": "2026-07-30",
14-
"evidence": "rendered as the record title of sys_permission_set in Setup's generic object views (objectui app-shell list/detail rendering via displayNameField)",
15-
"note": "display metadata."
13+
"verifiedAt": "2026-10-14",
14+
"evidenceScope": "cross-repo",
15+
"evidence": "objectui @b9814b334d8a, the .objectui-sha pin and unchanged at objectui main @524136ea7: packages/app-shell/src/services/builtinComponents.tsx:206 registers `{ key: 'label', label: 'Label' }` as a list column of the `permission` metadata resource, and packages/app-shell/src/views/metadata-admin/ResourceListPage.tsx:698 renders it as `row.item[c.key]` for every set Studio's permission-set list reads through `client.list('permission')`, which is GET /api/v1/meta/permission; framework: packages/metadata-protocol/src/protocol.ts#getMetaItems serves the authored body unprojected, so the authored label reaches that column.",
16+
"note": "display metadata. RE-VERIFIED 2026-10-14 (#23404): the previous evidence named the record title of the sys_permission_set row object in Setup's generic object views, and that object was retired at C3 stage 8; the Studio list column is the reader that remains."
1617
},
1718
"description": {
1819
"status": "live",
19-
"verifiedAt": "2026-07-30",
20-
"evidence": "persisted to sys_permission_set.description (plugin-security sys-permission-set.object.ts: textarea field, list columns + form); read from the authored set by permission-set-projection.ts (description: ps.description ?? null) and diffed on re-seed",
21-
"note": "Declared in #4001: the built-in default sets always authored it, but the schema could not represent it, so it was silently stripped at parse (ADR-0078 §3 inverse drift) — the .strict() gate surfaced the gap."
20+
"verifiedAt": "2026-10-14",
21+
"evidenceScope": "cross-repo",
22+
"evidence": "objectui @b9814b334d8a, the .objectui-sha pin and unchanged at objectui main @524136ea7: packages/app-shell/src/services/builtinComponents.tsx:207 registers `{ key: 'description', label: 'Description' }` as a list column of the `permission` metadata resource, and packages/app-shell/src/views/metadata-admin/ResourceListPage.tsx:698 renders it as `row.item[c.key]` for every set Studio's permission-set list reads through `client.list('permission')`, which is GET /api/v1/meta/permission; framework: packages/metadata-protocol/src/protocol.ts#getMetaItems serves the authored body unprojected, so the authored description reaches that column.",
23+
"note": "Declared in #4001: the built-in default sets always authored it, but the schema could not represent it, so it was silently stripped at parse (ADR-0078 §3 inverse drift) — the .strict() gate surfaced the gap. RE-VERIFIED 2026-10-14 (#23404): both readers the previous evidence named are deleted — the sys_permission_set row object (C3 stage 8) and the permission-set projection (C3 stage 7a). No framework-side reader of the authored key remains: packages/core/src/security/permission-set-row-definition.ts maps a legacy row INTO the key for the upgrade ceremony (a producer, not a reader), and the security catalog never reads it. Display-only, so the Studio list column is the whole of its claimed effect (README, the display/behaviour table)."
2224
},
2325
"packageId": {
2426
"status": "live",

0 commit comments

Comments
 (0)