Skip to content

docs(permissions): the hand-written pages describe the security catalog main serves, not the four retired row objects - #23322

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-22976-catalog-row-docs-sweep
Oct 13, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-22976-catalog-row-docs-sweep

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #22976
Clause-②: no (docs)

What this changes

After C3 stage 8 (#23222) and stage 7b (#23302), main serves positions, permission sets and capabilities as catalog definitions. The environment registry holds them and answers them by name (ADR-0131 D3), and assignments name them. Nine of the ten hand-written pages on the card still described the four retired row objects (sys_position, sys_permission_set, sys_position_permission_set, sys_capability) as stored tables. Some also described the ADR-0094 projector, the data-door write-through, binding rows, or the row-object Setup pages as live. This PR rewrites those passages to say what main does. Each rewrite was checked against source at main 404fc477e5. The tenth page, protocol/backward-compatibility.mdx, has one mention, and that mention is correct release history, so it is unchanged.

Docs only: 9 files, +149 / −136. There are no edits under content/docs/releases/**, CHANGELOG.md, ADRs (the domain:skills card #22978) or the generated reference pages.

Re-measure on main 404fc477e5

The grep sys_position|sys_permission_set|sys_capability over content/docs/**, excluding releases/** and references/**, matches exactly the card's 10 pages: authorization 11, permission-sets 6, delegated-administration 5, capabilities 3, positions 3, system-context 2, and 1 each on the other four. A second grep for the removed mechanisms (projector, projection, write-through, backfill, walled catalog data door, isRowActive, SystemObjectName.POSITION, the data-door URLs) adds no page. Its hits outside these pages describe mechanisms that are still live:

  • deployment/cli.mdx: "mutation projectors". The datasource-admin plugin still registers one.
  • kernel/cluster.mdx: the registry write-through, applyRegistryWriteThrough.
  • The seed-tenancy, membership and summary-null backfills, which are unrelated to the catalog.

The two generated reference pages that still mention the objects (references/api/protocol.mdx 3, references/identity/eval-user.mdx 2) render spec .describe() text. That text is residue for the 8-post stage, so those pages are not edited here.

Each mention was judged either a mis-statement or a correct retired statement. A correct "no row is written" or "retired" sentence is kept, as the card allows.

Page Line on main Verdict Done
concepts/metadata-lifecycle 141 Mis-statement. It names POST /api/v1/data/sys_permission_set as a clone path and says "the refusal does not name it yet". The row now names what the refusal names: the Clone action or the clone door.
data-modeling/objects 336 Mis-statement. It lists sys_position_permission_set as a member of the system-data bucket. Only the two assignment tables are listed.
deployment/environment-variables 70 Mis-statement. The grants-cache watched set lists three retired objects. Five objects, as in the code.
permissions/authorization 36 Mis-statement. Assignment is described as rows of sys_permission_set and sys_position. Catalog definitions, plus the two assignment rows that name them.
158, 169, 199, 207, 598 Correct ("no row is written"). Kept.
233, 244 (Two doors) Mis-statement. The projector, the data-door redirect, the data-layer provenance gate, and delete as reset on the data door. Rewritten to the metadata door: manage_metadata, operator-only under a wall, NOT_OVERRIDABLE naming the clone.
415–416 Mis-statement. "Setup's Deactivate action writes" the row's active column. Setup's catalog switch writes the activation ledger.
607 Mis-statement. The lint counts a sys_capability seed. A seed row is not counted.
permissions/capabilities 71, 210 Correct. Kept.
215 (callout) First sentence correct. "Clearing its active flag" implies the row is still served. The object is retired; the ceremony handles old rows.
permissions/delegated-administration 29, 37, 38, 53–54 Mis-statement. The example, the governed-table list, the action-flag row, and the zoo's binding-write case. Rewritten.
permissions/permission-sets 155 Correct. Kept.
241, 247–248 Junction row and data-layer anchor binding described as live. The junction is retired; everyone is derived, and the gate runs on the derived definition.
327 (adminScope example) Mis-statement (manageBindings, sys_position_permission_set). Example fixed.
344–347 "Data layer refuses forging", "position bindings" revoked on uninstall. What uninstall does on main.
366, 378 (the "record is a projection" section) Mis-statement. Rewritten as "One authoritative store — the definition".
409, 444 Data door and record described as live. Removed.
permissions/positions 11, 62 The junction and sys_position.name described as live. Reworded.
85 Correct. Kept.
Anchors section Anchor binding described as an admin act and as a data-layer gate. Derived definition; no caller writes either anchor.
permissions/system-context 111 (row 11) The projector skip is described as live. Annotated: the plugin no longer registers it; the module is still exported.
130 (row 23b) Correct (a name only a legacy row carries is refused). Kept.
187 (row 55b) On main it still names the data door on the three retired objects. Left to #23231, whose branch rewrites this row (see Shared pages).
410–412 "Resolves against the granting organization's own catalog row". The read targets an unregistered object and gets no rows.
protocol/backward-compatibility 75 Correct release history (17.2.0 retired sys_position.permissions). Kept.

Sources for the rewrites (main 404fc477e5)

  • Catalog read: packages/core/src/security/security-catalog.ts (module doc). Positions, permission sets and capabilities are read by name from the engine registry first, then from the metadata service. No row is read.
  • Assignments store names: sys-user-permission-set.object.ts:109 (permission_set, Field.text) and :86 (the legacy permission_set_id, plain text, which grants nothing). sys-user-position.object.ts:84 (position). The plugin registers three objects (objects/index.ts:12-14).
  • Setup under single and under a wall:
    • metadata-core/src/meta-write-capability.ts:82 admits a /meta write for manage_metadata or isSystem only.
    • :169-195 (walledCatalogWriteVerdict): under group or isolated, only the platform operator or isSystem may write the catalog. Under single the verdict is inert (:182).
    • Setup nav: plugin-security/src/security-plugin.ts:1543-1545 (/apps/setup/metadata/TYPE?scope=environment).
    • Setup's active switch, at the objectui pin 1fb1ced3: app-shell/src/views/metadata-admin/catalog-activation.ts and ResourceListPage.tsx:148. It writes POST /security/_activation/:type/:name.
  • Packaged sets: metadata-protocol/src/packaged-base-regime.ts:194-199 (the clone routes the refusal names) and managedItemSealedSentence (NOT_OVERRIDABLE / 403). Delete: protocol.ts:17772 (refusePackagedBaseRemoval). permission merges at read, so a delete removes only a stored row, and the package's definition stays served.
  • Grants cache: core/src/security/resolve-user-grants-cache.ts:117-125 (watched set). security-plugin.ts:1850-1866 bumps the metadata epoch on every metadata change.
  • Lint: lint/src/validate-capability-references.ts:16-26. A seed row is not a source.
  • Delegated-admin gate:
    • delegated-admin-gate.ts:131-149 (the governed set still names the two retired objects) and :396-405 (dispatch).
    • :818: manageAssignments also gates direct grants.
    • :993-1048: manageBindings and authorEnvironmentSets still take part in containment.
    • The zoo's binding cases are gone: showcase-permission-zoo.dogfood.test.ts:173-177.
  • Uninstall: plugin-security/src/cleanup-package-permissions.ts:13-25 revokes the grants that name a declared set.
  • Anchors: plugin-security/src/builtin-positions.ts:121 registers guest with no permissionSets. :138 derives everyone from the baseline.
  • Legacy reads: objectql/src/engine.ts:10276 (resolveObjectName throws OBJECT_NOT_FOUND for an unregistered object). plugin-security/src/auto-org-admin-grant.ts:154-176 catches the error and answers [].
  • Old databases: cli/src/utils/organization-ownership-apply.ts:38-53 and :399-405. Under single, authored sets and positions are converted. Authored capability rows are reported. Seeded copies are deleted.

Measured against ADR-0131 D2/D3 text

The ADR's original reading was that Setup authoring under single needs no Studio capability (the organization admin's object grants). The ADR's own text withdraws that reading: the 2026-10-10 note in D2 and D3 (#22621) says Setup authoring under single requires manage_metadata. main does what the withdrawal says (meta-write-capability.ts:82), and the pages follow main.

Shared pages

Acceptance notes

  • Not in this card (family residue, noted, not filed):
    • 8-post:
      • The spec .describe() texts still cite the retired objects: permission.zod.ts packageId and managedBy ("persisted on sys_permission_set records", bootstrapDeclaredPermissions), AdminScopeSchema.manageBindings, and sys-user-position.object.ts position ("references sys_position.name"). Two generated reference pages render that text.
      • adminScope.manageBindings and authorEnvironmentSets are spec-declared keys whose primary gates target objects main no longer registers. They now take part only in strict containment. The showcase still declares both as false. The permission liveness row's adminScope evidence still cites the two retired objects.
    • 7a: createPermissionSetWriteThrough and registerPermissionSetProjection are still exported from @objectstack/plugin-security (index.ts:79-80), but nothing registers them.
    • C7b: the legacy-id reads of sys_permission_set and sys_position (auto-org-admin-grant.ts:343-356, delegated-admin-gate.ts:1317, :1330, and the grant-name backfill) throw OBJECT_NOT_FOUND. The errors are caught, so each read answers no rows.
  • delegated-administration.mdx says "sys_member is not one of the gate's governed objects" (the invitation role cap). GOVERNED_OBJECTS lists it (delegated-admin-gate.ts:148). This is unrelated to the catalog objects, so it is not changed here.
  • permissions/administrator-guide.mdx is not added to the page list. It names none of the four objects and none of the removed mechanisms. Its Setup walkthrough was not checked against the console at the pin.

Verification

Local runs on head 260137da82. CI is not complete yet.

  • Derived gates. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 44 commands; all 44 ran and exited 0. --ran reconciles: "44 derived famil(ies) accounted for — 44 run, 0 NOT-MEASURED (a DERIVED zero — all 44 recorded an exit code and none of them is 3)". Selected verdict lines:
    • check:doc-anchors: 499 internal fragment links resolve, including the new permission-sets#package-suggestion--isdefault-adr-0090-d5.
    • check:system-context-census: "OK — 133 elevation read sites … the page cites 126 symbol(s) against 126 required".
    • check:doc-authoring, check:corpus-claim-drift, check:role-word, check:overlay-whitelist-table, check:docs-transcript-drift, spec check:docs ("226 generated files in sync") and spec check:skill-examples (263 prose examples type-check): all green.
    • Two first runs exited 3 with PREREQUISITE NOT MET. Both were re-run after the lock-held builds of @objectstack/lint... and @objectstack/client-react... (VERDICT command-exit 0), and both then exited 0.
  • Links. lychee 0.24.2 with check-links.yml's argv (--offline --root-dir content --fallback-extensions mdx,md --config lychee.toml over the four globs): "2460 Total … 0 Errors". node scripts/check-adr-links.mjs: 730 links resolve.
  • MDX compile. @mdx-js/mdx 3.1.1 with remark-gfm compiled all nine edited pages (9/9). Control: an unclosed Callout fails with "Expected a closing tag".
  • skip-changeset. The diff is only content/docs/**. Of the 71 non-private package.json manifests, none has a files[] entry naming content/. Control: the same scan for liveness matches packages/spec.

Generated by Claude Code

…og main serves, not the four retired row objects

The catalog-row docs sweep after stage 8. Positions, permission sets and
capabilities are definitions the environment registry serves by name
(ADR-0131 D3); assignments name them. The pages no longer describe the
sys_permission_set projection, the data-door write-through, the binding
rows or the row-object Setup pages as live.

Claude-Session: https://claude.ai/code/session_012zwsLMxQBwHUYJgPyrpEvx
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation labels Oct 13, 2026
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 13, 2026
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 13, 2026 19:12
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 13, 2026 19:12
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 13, 2026
Merged via the queue into main with commit 4d4040c Oct 13, 2026
45 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-22976-catalog-row-docs-sweep branch October 13, 2026 19:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

C3 #15204 docs sweep: ten content/docs pages still describe the four retired catalog row objects; draft now, land after stage 8

2 participants