Repository navigation
Commit 73c7dc4
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
- .changeset
- packages/spec/liveness
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
14 | | - | |
15 | | - | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
19 | | - | |
20 | | - | |
21 | | - | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
22 | 24 | | |
23 | 25 | | |
24 | 26 | | |
| |||
0 commit comments