diff --git a/.changeset/permission-form-profile-concept-retired.md b/.changeset/permission-form-profile-concept-retired.md new file mode 100644 index 0000000000..9336c9f1ff --- /dev/null +++ b/.changeset/permission-form-profile-concept-retired.md @@ -0,0 +1,17 @@ +--- +"@objectstack/spec": patch +"@objectstack/platform-objects": patch +--- + +`permissionForm` stops teaching the Profile concept ADR-0090 D2 removed — in the shipped section description, and in all four locales. + +The form's `Identity` section description read *"Permission Sets stack on top of a Profile to grant additional access. Profiles are the base set assigned 1:1 to each user."* That is the model ADR-0090 D2 retired: it deleted `isProfile` from `PermissionSetSchema` (removed, not deprecated), leaving permission sets as the only capability container. The same file's docstring claimed the form serves a `profile` metadata kind alongside `permission`, and carried a half-edited sentence — *"The only flags are minimal (ADR-0090 D2 removed the Profile concept) so admins can see and toggle it explicitly"* — that named no flag and whose `it` referred to nothing. + +The description is the half that ships, and it shipped translated: `en`, `zh-CN`, `ja-JP` and `es-ES` all carried it. None of the three translated leaves has a recorded source hash (`metadataForms.permission.*` has zero entries in any of the three `*.source-hashes.generated.ts` tables, against 158/191/191 `metadataForms.*` entries overall), so they are legacy-trusted: changing the English alone would have left three languages teaching the retired concept under a green build, with nothing reporting it stale. All four move together here. + +- **The description now states the v2 model**: permission sets are the only capability container, a user gets the union of every set they hold so sets only ever add access, and positions distribute sets to people — the same three facts `PermissionSetSchema`'s own header states (`packages/spec/src/security/permission.zod.ts`). +- **The docstring says what the tree enforces**: the form serves `permission` and only `permission`. `METADATA_FORM_REGISTRY` has no `profile` key, `MetadataTypeSchema` admits no `profile` kind, and `PermissionSetSchema` answers an authored `isProfile` or `profiles` with a retirement tombstone rather than a silent strip. +- **The subjectless sentence is replaced by a true one**: the form surfaces no flag, because `isDefault` (ADR-0090 D5) is the schema's only boolean and it records a boot-time binding hint, not a grant. +- **One further translated leaf moves**: the zh-CN label for the `permission` form group read `"权限集 / 配置文件"`, appending the retired concept to a source label that is plain `Permission Set` (`metadata-plugin.zod.ts`). `ja-JP` and `es-ES` already rendered the source faithfully. + +No schema, key, registry entry or export moves — the accept set is byte-identical. diff --git a/packages/platform-objects/src/apps/translations/en.metadata-forms.generated.ts b/packages/platform-objects/src/apps/translations/en.metadata-forms.generated.ts index 25add2353d..ddbe31055f 100644 --- a/packages/platform-objects/src/apps/translations/en.metadata-forms.generated.ts +++ b/packages/platform-objects/src/apps/translations/en.metadata-forms.generated.ts @@ -1460,7 +1460,7 @@ export const enMetadataForms: NonNullable = { sections: { identity: { label: "Identity", - description: "Permission Sets stack on top of a Profile to grant additional access. Profiles are the base set assigned 1:1 to each user." + description: "Permission sets are the only capability container: a user gets the union of every set they hold, so sets only ever add access. Positions distribute sets to people." }, system_permissions: { label: "System Permissions", diff --git a/packages/platform-objects/src/apps/translations/es-ES.metadata-forms.generated.ts b/packages/platform-objects/src/apps/translations/es-ES.metadata-forms.generated.ts index 36ab94e78b..023e6f5d54 100644 --- a/packages/platform-objects/src/apps/translations/es-ES.metadata-forms.generated.ts +++ b/packages/platform-objects/src/apps/translations/es-ES.metadata-forms.generated.ts @@ -1460,7 +1460,7 @@ export const esESMetadataForms: NonNullable = sections: { identity: { label: "Identidad", - description: "Los conjuntos de permisos se apilan sobre un perfil para conceder acceso adicional. Los perfiles son el conjunto base asignado 1:1 a cada usuario." + description: "Los conjuntos de permisos son el único contenedor de capacidades: un usuario obtiene la unión de todos los conjuntos que tiene, así que un conjunto solo puede añadir acceso. Las posiciones distribuyen los conjuntos a las personas." }, system_permissions: { label: "Permisos del sistema", diff --git a/packages/platform-objects/src/apps/translations/ja-JP.metadata-forms.generated.ts b/packages/platform-objects/src/apps/translations/ja-JP.metadata-forms.generated.ts index 2b26f617a7..1901c20487 100644 --- a/packages/platform-objects/src/apps/translations/ja-JP.metadata-forms.generated.ts +++ b/packages/platform-objects/src/apps/translations/ja-JP.metadata-forms.generated.ts @@ -1460,7 +1460,7 @@ export const jaJPMetadataForms: NonNullable = sections: { identity: { label: "ID", - description: "権限セットはプロファイルに追加アクセス権を重ねる。プロファイルは各ユーザーに 1:1 で割り当てる基本セット。" + description: "権限セットは唯一の能力コンテナです。ユーザーは保持するすべてのセットの和集合を得るため、セットはアクセス権を追加することしかできません。ポジションがセットを人に配分します。" }, system_permissions: { label: "システム権限", diff --git a/packages/platform-objects/src/apps/translations/zh-CN.metadata-forms.generated.ts b/packages/platform-objects/src/apps/translations/zh-CN.metadata-forms.generated.ts index d9ac3d9fe3..b6a40c4697 100644 --- a/packages/platform-objects/src/apps/translations/zh-CN.metadata-forms.generated.ts +++ b/packages/platform-objects/src/apps/translations/zh-CN.metadata-forms.generated.ts @@ -1456,11 +1456,11 @@ export const zhCNMetadataForms: NonNullable = description: "Documentation navigation spine — ordered groups with derived membership (ADR-0046 §6)" }, permission: { - label: "权限集 / 配置文件", + label: "权限集", sections: { identity: { label: "身份", - description: "权限集叠加在配置文件之上,用于授予额外访问权限。配置文件是按 1:1 分配给每个用户的基础权限集。" + description: "权限集是唯一的能力容器:用户获得其持有的所有权限集的并集,因此权限集只会增加访问权限。岗位负责把权限集分配给人。" }, system_permissions: { label: "系统权限", diff --git a/packages/spec/src/security/permission.form.ts b/packages/spec/src/security/permission.form.ts index 1986ed530e..167ab215ab 100644 --- a/packages/spec/src/security/permission.form.ts +++ b/packages/spec/src/security/permission.form.ts @@ -5,10 +5,16 @@ import { defineForm } from '../ui/view.zod'; /** * PermissionSet — canonical FormView layout. * - * Used for both `permission` (additive permission grant bundles) and - * `profile` (the base permission set assigned to every user). The only - * flags are minimal (ADR-0090 D2 removed the Profile concept) - * so admins can see and toggle it explicitly. + * Serves the `permission` metadata kind, and only that one. There is no + * Profile concept: ADR-0090 D2 removed it (`isProfile` deleted, not + * deprecated), leaving permission sets as the only capability container — + * union-merged and purely additive. So `METADATA_FORM_REGISTRY` has no + * `profile` key, `MetadataTypeSchema` admits no `profile` kind, and + * `PermissionSetSchema` answers an authored `isProfile` or `profiles` with a + * retirement tombstone rather than a silent strip. + * + * The form surfaces no flag: `isDefault` (ADR-0090 D5) is the schema's only + * boolean and it records a boot-time binding hint, not a grant. * * The object/field permission maps are intentionally kept as JSON for * now — they're typically managed via the dedicated permission matrix @@ -21,7 +27,7 @@ export const permissionForm = defineForm({ { label: 'Identity', description: - 'Permission Sets stack on top of a Profile to grant additional access. Profiles are the base set assigned 1:1 to each user.', + 'Permission sets are the only capability container: a user gets the union of every set they hold, so sets only ever add access. Positions distribute sets to people.', columns: 2, fields: [ { field: 'name', required: true, colSpan: 1, helpText: 'Machine name (snake_case)' },