Skip to content

Commit b3c8d0d

Browse files
committed
docs(spec): comments that named the declared-capability seeder say the registry is a declared capability's one home
1 parent b479134 commit b3c8d0d

5 files changed

Lines changed: 22 additions & 29 deletions

File tree

‎packages/spec/src/kernel/metadata-plugin.zod.ts‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ export const MetadataTypeSchema = lazySchema(() => z.enum([
169169
// `declared ≠ enforced` that #5271 closed for `api`. `PLURAL_TO_SINGULAR`
170170
// has mapped `capabilities` → `capability` since #5870, `AppPlugin`
171171
// registers stack-declared capabilities under that exact name, and
172-
// `bootstrapDeclaredCapabilities` reads them back — but the kind was absent
172+
// the declared-capability seeder (since retired, ADR-0131 D3) read them back —
173+
// but the kind was absent
173174
// from this enum, from `BUILTIN_METADATA_TYPE_SCHEMAS` and from
174175
// `DEFAULT_METADATA_TYPE_REGISTRY`, so it resolved no schema and
175176
// `PUT /api/v1/meta/capability/:name` stored ANY JSON on an authorization
@@ -1134,9 +1135,9 @@ export const DEFAULT_METADATA_TYPE_REGISTRY: MetadataTypeRegistryEntryParsed[] =
11341135
//
11351136
// The package-declaration channel is untouched: `AppPlugin` registers stack
11361137
// `capabilities[]` through `registerInMemory`, and the filesystem loader
1137-
// globs `filePatterns` — neither goes through `saveMetaItem`, so
1138-
// `bootstrapDeclaredCapabilities` still seeds `sys_capability` exactly as
1139-
// before. `OS_METADATA_WRITABLE=capability` remains the ONE documented
1138+
// globs `filePatterns` — neither goes through `saveMetaItem`, so a package's
1139+
// declarations still reach the registry, their one home (ADR-0131 D3).
1140+
// `OS_METADATA_WRITABLE=capability` remains the ONE documented
11401141
// operator escape hatch (ADR-0005), and behind it the write is now judged by
11411142
// `CapabilityDeclarationSchema` (422) instead of being stored unvalidated.
11421143
//

‎packages/spec/src/kernel/metadata-type-schemas.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ const BUILTIN_METADATA_TYPE_SCHEMAS: Partial<Record<MetadataType, z.ZodType>> =
169169
// authorization capabilities (ADR-0066 D1). The kind was produced and read
170170
// back long before it resolved a schema: `PLURAL_TO_SINGULAR` maps
171171
// `capabilities` → `capability` (#5870), `AppPlugin` registers stack-declared
172-
// ones under that name, and `bootstrapDeclaredCapabilities` reads them back to
173-
// seed `sys_capability`. Yet `getMetadataTypeSchema('capability')` answered
172+
// ones under that name, and the declared-capability seeder (since retired,
173+
// ADR-0131 D3) read them back to seed `sys_capability`. Yet `getMetadataTypeSchema('capability')` answered
174174
// `undefined`, so `saveMetaItem` took its documented "unregistered type →
175175
// store without validation" branch and `PUT /meta/capability/:name` accepted
176176
// ANY JSON — on an AUTHORIZATION surface, where `systemPermissions` /

‎packages/spec/src/meta-spelling/manifest-collection-spelling.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ export const PLURAL_TO_SINGULAR: Record<string, string> = {
7676
positions: 'position',
7777
permissions: 'permission',
7878
// [ADR-0066 D1, #5870] Package-declared authorization capabilities. The
79-
// singular form is what `bootstrapDeclaredCapabilities` reads back
80-
// (`readDeclared(ql, 'capability')`) and what `AppPlugin` already registers
79+
// singular form is what the registry and the security catalog read back
80+
// (`listItems('capability')`) and what `AppPlugin` already registers
8181
// under; without the mapping the registration seam stored them as
8282
// `'capabilities'`, a store nothing reads.
8383
capabilities: 'capability',

‎packages/spec/src/security/capabilities.ts‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,8 @@ export const PLATFORM_CAPABILITY_NAMES: ReadonlySet<string> = new Set(
9393
* capability of its own — the counterpart, on the declaration side, of the
9494
* curated {@link PLATFORM_CAPABILITIES}. Authored via {@link defineCapability}
9595
* and collected on a stack's `capabilities` array, these declarations flow
96-
* EXPLICITLY into the `sys_capability` registry at boot with `managed_by:
97-
* 'package'` + `package_id` provenance (seeded by
98-
* `@objectstack/plugin-security`'s `bootstrapDeclaredCapabilities`).
96+
* EXPLICITLY into the registry at boot under their owning package (ADR-0131
97+
* D3); no `sys_capability` row is written for them.
9998
*
10099
* This replaces the old implicit "derive an untitled capability from whatever a
101100
* permission set happens to reference in `systemPermissions[]`" back-door: a
@@ -127,8 +126,8 @@ export const PLATFORM_CAPABILITY_NAMES: ReadonlySet<string> = new Set(
127126
* - **The shape is `.strict()`.** Unlike `api` (which is on that suite's
128127
* `STILL_STRIP` list because `ApiEndpointSchema` doubles as the parser for
129128
* STORED rows carrying `packageId` / `state`), nothing re-parses a stored
130-
* `sys_capability` row through this schema — `bootstrapDeclaredCapabilities`
131-
* reads named fields off the body (`capabilityRowFields`). So closing it
129+
* `sys_capability` row through this schema — no row is written for a
130+
* declared capability (ADR-0131 D3). So closing it
132131
* costs nothing and buys the declared = enforced posture an AUTHORIZATION
133132
* surface should have had from the start.
134133
*/

‎packages/spec/src/security/high-privilege.ts‎

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,16 @@ function coerceRecord(v: unknown): Record<string, unknown> | undefined {
3131
* The predicates are pure and synchronous — they read one permission-set
3232
* definition and nothing else — so the one fact they cannot discover for
3333
* themselves is which capability names this stack DECLARED. The caller holds
34-
* it: at boot from the stack's own `capabilities:` DECLARATIONS — and from
35-
* the `sys_capability` rows carrying `managed_by: 'package'` provenance only
36-
* ONCE THE SEEDER HAS WRITTEN THEM — at authoring time from the stack's own
37-
* `capabilities` array.
34+
* it: at boot from the stack's own `capabilities:` DECLARATIONS in the
35+
* registry, at authoring time from the stack's own `capabilities` array.
3836
*
39-
* ⚠️ [#18603] Why the boot half names the DECLARATIONS and not the rows: the
40-
* ADR-0090 D5 anchor binding (`bindBaselineToEveryone` in
41-
* `@objectstack/plugin-security`) runs BEFORE `bootstrapDeclaredCapabilities`,
42-
* the seeder that WRITES those `managed_by: 'package'` rows, and that order is
43-
* fixed by two other constraints — the binding must follow the seeding of the
44-
* `everyone` anchor it binds to, and precede the audience-binding suggestion
45-
* reconciliation. On a first boot the table is therefore EMPTY at the bind
46-
* moment, and "omission refuses" below turns that emptiness into a silent
47-
* refusal of every declared token. A boot caller reads the declarations
48-
* through the seeder's own two-step — the ObjectQL registry first, the
49-
* metadata service as the fallback — as `readDeclaredCapabilityContext`
50-
* (`@objectstack/plugin-security`) does.
37+
* ⚠️ [#18603] Why the boot half names the DECLARATIONS and not the rows: no
38+
* `sys_capability` row is written for a declared capability — the registry is
39+
* its one home (ADR-0131 D3) — so a row read would find nothing, and
40+
* "omission refuses" below would turn that emptiness into a silent refusal of
41+
* every declared token. A boot caller reads the declarations from the ObjectQL
42+
* registry first, the metadata service as the fallback, as
43+
* `readDeclaredCapabilityContext` (`@objectstack/plugin-security`) does.
5144
*
5245
* ⛔ Never synthesize this from the set under test. The point of the input is
5346
* that a set cannot vouch for its own tokens; a "declared" list derived from

0 commit comments

Comments
 (0)