Skip to content

Commit d0fe050

Browse files
fix(spec): the Permission Set, Position and view form help texts Setup shows are plain admin copy (#23870)
Fixes #23853 Clause-②: no ## What changed Six help texts an administrator reads in Setup carried ADR numbers. Each one is now plain admin copy. The ADR reference moved to the comment beside the form row, the shape of #23817. | Form leaf | Before | After | |---|---|---| | `permission` · `isDefault` | App baseline for the everyone position (ADR-0090 D5): an app-level set is auto-bound at boot; a package-level set becomes an install-time suggestion an admin confirms. Default false. | Gives this set to everyone who signs in, through the built-in everyone position. A set the app itself declares is granted at startup; a set from an installed package becomes a suggestion an admin confirms in Setup. A set with high-privilege permissions is never granted this way. Default false. | | `permission` · `managedBy` | Record provenance (ADR-0086 D3): who owns this set across upgrades. | Who owns this set: Package means it ships with a package and package upgrades update it; Platform and User mean it was created in this environment and upgrades leave it alone. | | `permission` · `packageId` | Owning package id for a package-shipped set (ADR-0086 D3). Leave empty for an environment-authored set. | The package that ships this set; a value naming any other package is refused. Leave empty for a set created in this environment. | | `permission` · `adminScope` | Delegated administration (ADR-0090 D12): lets holders ... | Delegated administration: lets holders ... (rest unchanged) | | `position` · `delegatable` | Holders may delegate this position themselves, time-boxed and with a reason (ADR-0091 D3). Default false — delegation is admin-only. | The same sentence without "(ADR-0091 D3)". | | `view` · section `end_user_controls` description | What end users can do on this view — quick filters, filter tabs, visualization switching (ADR-0047, Airtable Interface parity). | What end users can do on this view — quick filters, filter tabs, visualization switching. | ### Each sentence checked against the code that honours the field - `isDefault`: `PermissionSetSchema.isDefault`'s docblock and `plugin-security`'s `builtin-positions.ts`. An app-level set is auto-bound to the `everyone` position at boot. Every authenticated member holds that position implicitly. A package-level set materializes a `sys_audience_binding_suggestion` that an admin confirms in Setup. A high-privilege set cannot be bound to the anchor. - `managedBy`: `package` rows are re-seeded on upgrade. `platform` and `user` rows are environment config that package seeding never touches. - `packageId`: a value that disagrees with the package that ships the set, or that the set is saved into, is refused at every door (`judgePermissionSetOwnerBinding`). That includes any value on a set no package ships. - `adminScope` and `delegatable`: the rest of each text was already operational, and #23488 aligned the `adminScope` keys with the live schema. Only the ADR prefix moved. - The view's end-user controls: the `userFilters` `tabs` element (`view.zod.ts`) and `appearance.allowedVisualizations` are live keys, so "filter tabs" and "visualization switching" stay. The retired `tabs` repeater is not named. ### Translations - `pnpm i18n:extract` regenerated `en.metadata-forms.generated.ts`: 6 leaves. - The zh-CN, ja-JP and es-ES values for the same 6 leaves were hand-written translations of the old wording, and merge mode keeps them. So they were rewritten in place to the new meaning, before the extract. Values only: no key was added or removed. - The `*.source-hashes.generated.ts` tables did not change. "Setup" stays untranslated, as the sibling leaves in each locale already leave it. ### Test `packages/platform-objects/src/apps/setup-copy-vocabulary.test.ts` gains two cases. No assertion was deleted. - **Bright leg:** across all four `metadataForms` bundles, each of the six leaves must be a string (the population cannot shrink) and must carry no ADR number, no decision id (D plus digits), no `finding F`, no `emit()` and no `kernel`. It uses the matcher this file already uses. - **Dark leg:** the same walk over the replaced prose names all six leaves. The file docblock's population item 3 names the six leaves. No other test pins these strings. `git grep` for the old wording hits only `.describe()` text, `content/docs/references/` and changesets, all outside this card. ### Changeset `.changeset/23853-form-help-texts-plain.md` is a `patch` for `@objectstack/spec` and `@objectstack/platform-objects`, with `Clause-②: no`. No key, type, schema or accept/refuse result changes. ## Verification (head `01167a02`) - Ablation, one leg, through `scripts/ablation-replace.mjs`. "(ADR-0090 D12)" was put back into the zh-CN `adminScope` leaf. The zh-CN case went red, naming `zh-CN.metadataForms.permission.fields.adminScope.helpText (an ADR number, a decision id)`. The restore left the blob equal to HEAD (`48bc7f4d7c85`) and `git diff HEAD` empty. - `pnpm --filter @objectstack/platform-objects test`: 71 files, 1108 tests passed. `typecheck`: exit 0. - `pnpm --filter @objectstack/spec build`, then `check:generated`: exit 0, all 14 generated artifacts up to date. - `pnpm check:i18n`: exit 0, 10 packages in sync. The first run exited 3 because the extract closure was not built (a prerequisite, not a finding). It passed after the closure the gate names was built. - `pnpm check:i18n-stale-fill`: exit 0, 0 stale fills. - `dispatch-gates --commands` derived 86 families. 84 exited 0. 2 exited 3 on prerequisites and are NOT MEASURED locally, left to CI: - `check-plugin-teardown-shape --self-test`: shallow clone. - `check:dual-build-cjs-loads`: not every package is built. - `--ran` reconciliation: 86 accounted for, 0 UNRUN. - `main` was merged at `0af559e8` through `scripts/pm/os-regen-merge.sh`. The incoming commits touch none of these files and no generated artifact, so there was nothing to regenerate. ## Acceptance notes - The card's acceptance holds: none of the six strings contains `ADR-`, a decision id, `finding F`, `emit()` or `kernel`, in source or in any locale. The `en` and locale files are regenerated. - The full stops match the sibling help texts in each file. Every rewritten text already ended with one, and so does the sibling section description `Chart-specific configuration.` - The `managedBy` option labels ("Package (upgrade-owned metadata)", "Platform (environment config)", "User (environment config)") carry no ADR vocabulary and are outside this card's file surface. They are unchanged. - #23829's `domain:services` object descriptions are not addressed here. PR #23846 regenerates the same `*.metadata-forms.generated.ts` files; whichever PR lands second merges `main` and regenerates. --- _Generated by [Claude Code](https://claude.ai/code/session_01JzEWBwPjA5XW27bESPUVWw)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 94114c1 commit d0fe050

9 files changed

Lines changed: 114 additions & 35 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
'@objectstack/spec': patch
3+
'@objectstack/platform-objects': patch
4+
---
5+
6+
Clause-②: no
7+
8+
Six help texts an administrator reads in Setup no longer carry ADR numbers. On the Permission Sets edit form,
9+
`isDefault`, `managedBy` and `packageId` are rewritten as plain sentences that say what the field does, and
10+
`adminScope` drops its "(ADR-0090 D12)" prefix. On the Positions edit form, `delegatable` drops "(ADR-0091 D3)".
11+
The view form's End-user controls description drops "(ADR-0047, Airtable Interface parity)".
12+
13+
The ADR references moved to the comments beside the form rows. The generated metadata-forms translations carry
14+
the new wording in en, zh-CN, ja-JP and es-ES. No key, type or accept/refuse result changes.

‎packages/platform-objects/src/apps/setup-copy-vocabulary.test.ts‎

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@
2323
* 2. every leaf of the four committed `objects` bundles;
2424
* 3. the type-level `label` / `description` of the four `metadataForms`
2525
* bundles — the sentence a Setup metadata page (Positions, Capabilities,
26-
* Permission Sets) shows under its title. Section descriptions and field
27-
* `helpText` of those forms are the spec's form copy and are not judged
28-
* here;
26+
* Permission Sets) shows under its title, plus the six form leaves named
27+
* in `FORM_HELP_LEAVES` (the Permission Sets and Positions help texts and
28+
* the view form's End-user controls description). The other section
29+
* descriptions and field `helpText` of those forms are the spec's form
30+
* copy and are not judged here;
2931
* 4. `SETUP_APP` and this package's `SETUP_NAV_CONTRIBUTIONS`, and the
3032
* hand-authored `apps.setup` subtree of each locale.
3133
*
@@ -172,6 +174,55 @@ describe('Setup copy carries no design-record vocabulary', () => {
172174
expect(offenders(strings)).toEqual([]);
173175
});
174176

177+
// The help texts an admin reads on Setup's Permission Sets and Positions edit
178+
// forms, and the view form's End-user controls section. Each one carried a
179+
// decision-record reference until the spec form source moved it into the
180+
// comment beside the row; `en` is regenerated from that source, so judging
181+
// the four bundles judges the source too.
182+
const FORM_HELP_LEAVES = [
183+
['permission', 'fields', 'isDefault', 'helpText'],
184+
['permission', 'fields', 'managedBy', 'helpText'],
185+
['permission', 'fields', 'packageId', 'helpText'],
186+
['permission', 'fields', 'adminScope', 'helpText'],
187+
['position', 'fields', 'delegatable', 'helpText'],
188+
['view', 'sections', 'end_user_controls', 'description'],
189+
] as const;
190+
191+
function formHelpLeaves(bundle: unknown, locale: string): Array<[string, string]> {
192+
return FORM_HELP_LEAVES.map((path) => {
193+
const value = path.reduce<unknown>((node, key) => (node as Record<string, unknown> | undefined)?.[key], bundle);
194+
const at = `${locale}.metadataForms.${path.join('.')}`;
195+
expect(value, `${at} is in the population`).toBeTypeOf('string');
196+
return [at, value as string];
197+
});
198+
}
199+
200+
it.each(Object.keys(FORM_BUNDLES))('the Permission Set, Position and view form help texts of the %s metadataForms bundle', (locale) => {
201+
const strings = formHelpLeaves(FORM_BUNDLES[locale as keyof typeof FORM_BUNDLES], locale);
202+
expect(strings).toHaveLength(FORM_HELP_LEAVES.length);
203+
expect(offenders(strings)).toEqual([]);
204+
});
205+
206+
it('the form help-text assertion fires on the prose it replaced', () => {
207+
// Dark leg: the same walk over a bundle carrying the replaced wording must
208+
// name every leaf, so a walk that reaches nothing cannot pass above.
209+
const replaced = {
210+
permission: { fields: {
211+
isDefault: { helpText: 'App baseline for the everyone position (ADR-0090 D5): an app-level set is auto-bound at boot.' },
212+
managedBy: { helpText: 'Record provenance (ADR-0086 D3): who owns this set across upgrades.' },
213+
packageId: { helpText: 'Owning package id for a package-shipped set (ADR-0086 D3).' },
214+
adminScope: { helpText: 'Delegated administration (ADR-0090 D12): lets holders of this set administer one business-unit subtree.' },
215+
} },
216+
position: { fields: {
217+
delegatable: { helpText: 'Holders may delegate this position themselves, time-boxed and with a reason (ADR-0091 D3).' },
218+
} },
219+
view: { sections: {
220+
end_user_controls: { description: 'What end users can do on this view (ADR-0047, Airtable Interface parity).' },
221+
} },
222+
};
223+
expect(offenders(formHelpLeaves(replaced, 'replaced'))).toHaveLength(FORM_HELP_LEAVES.length);
224+
});
225+
175226
it('the Setup app, its nav contributions, and every locale\'s apps.setup translations', () => {
176227
const strings: Array<[string, string]> = [];
177228
copyStrings(SETUP_APP, 'SETUP_APP', strings);

‎packages/platform-objects/src/apps/translations/en.metadata-forms.generated.ts‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,7 @@ export const enMetadataForms: NonNullable<TranslationData['metadataForms']> = {
10191019
},
10201020
end_user_controls: {
10211021
label: "End-user controls",
1022-
description: "What end users can do on this view — quick filters, filter tabs, visualization switching (ADR-0047, Airtable Interface parity)."
1022+
description: "What end users can do on this view — quick filters, filter tabs, visualization switching."
10231023
},
10241024
navigation_sharing: {
10251025
label: "Navigation & sharing",
@@ -2330,23 +2330,23 @@ export const enMetadataForms: NonNullable<TranslationData['metadataForms']> = {
23302330
},
23312331
isDefault: {
23322332
label: "Is Default",
2333-
helpText: "App baseline for the everyone position (ADR-0090 D5): an app-level set is auto-bound at boot; a package-level set becomes an install-time suggestion an admin confirms. Default false."
2333+
helpText: "Gives this set to everyone who signs in, through the built-in everyone position. A set the app itself declares is granted at startup; a set from an installed package becomes a suggestion an admin confirms in Setup. A set with high-privilege permissions is never granted this way. Default false."
23342334
},
23352335
managedBy: {
23362336
label: "Managed By",
2337-
helpText: "Record provenance (ADR-0086 D3): who owns this set across upgrades."
2337+
helpText: "Who owns this set: Package means it ships with a package and package upgrades update it; Platform and User mean it was created in this environment and upgrades leave it alone."
23382338
},
23392339
packageId: {
23402340
label: "Package Id",
2341-
helpText: "Owning package id for a package-shipped set (ADR-0086 D3). Leave empty for an environment-authored set."
2341+
helpText: "The package that ships this set; a value naming any other package is refused. Leave empty for a set created in this environment."
23422342
},
23432343
systemPermissions: {
23442344
label: "System Permissions",
23452345
helpText: "List of system capability keys"
23462346
},
23472347
adminScope: {
23482348
label: "Admin Scope",
2349-
helpText: "Delegated administration (ADR-0090 D12): lets holders of this set administer one business-unit subtree. businessUnit is the subtree root (sys_business_unit.name) and is required, non-blank; includeSubtree defaults to true; manageAssignments defaults to false and lets the holder assign people to positions, and grant sets directly, inside that subtree; a delegate may hand out only the sets named in assignablePermissionSets. Leave empty for a set that delegates nothing."
2349+
helpText: "Delegated administration: lets holders of this set administer one business-unit subtree. businessUnit is the subtree root (sys_business_unit.name) and is required, non-blank; includeSubtree defaults to true; manageAssignments defaults to false and lets the holder assign people to positions, and grant sets directly, inside that subtree; a delegate may hand out only the sets named in assignablePermissionSets. Leave empty for a set that delegates nothing."
23502350
},
23512351
objects: {
23522352
label: "Objects",
@@ -2391,7 +2391,7 @@ export const enMetadataForms: NonNullable<TranslationData['metadataForms']> = {
23912391
},
23922392
delegatable: {
23932393
label: "Delegatable",
2394-
helpText: "Holders may delegate this position themselves, time-boxed and with a reason (ADR-0091 D3). Default false — delegation is admin-only."
2394+
helpText: "Holders may delegate this position themselves, time-boxed and with a reason. Default false — delegation is admin-only."
23952395
}
23962396
}
23972397
},

‎packages/platform-objects/src/apps/translations/es-ES.metadata-forms.generated.ts‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,7 @@ export const esESMetadataForms: NonNullable<TranslationData['metadataForms']> =
10191019
},
10201020
end_user_controls: {
10211021
label: "Controles de usuario final",
1022-
description: "Lo que los usuarios finales pueden hacer en esta vista: filtros rápidos, pestañas de filtro, cambio de visualización (ADR-0047, paridad con Airtable Interface)."
1022+
description: "Lo que los usuarios finales pueden hacer en esta vista: filtros rápidos, pestañas de filtro, cambio de visualización."
10231023
},
10241024
navigation_sharing: {
10251025
label: "Navegación y uso compartido",
@@ -2330,23 +2330,23 @@ export const esESMetadataForms: NonNullable<TranslationData['metadataForms']> =
23302330
},
23312331
isDefault: {
23322332
label: "Predeterminado",
2333-
helpText: "Línea base de la aplicación para la posición everyone (ADR-0090 D5): un conjunto de nivel de aplicación se vincula automáticamente al arrancar; uno de nivel de paquete se convierte en una sugerencia que el administrador confirma al instalar. false por defecto."
2333+
helpText: "Concede este conjunto a todos los que inician sesión, mediante la posición integrada everyone. Un conjunto que declara la propia aplicación se concede al arrancar; uno de un paquete instalado se convierte en una sugerencia que un administrador confirma en Setup. Un conjunto con permisos de alto privilegio nunca se concede así. false por defecto."
23342334
},
23352335
managedBy: {
23362336
label: "Gestionado por",
2337-
helpText: "Procedencia del registro (ADR-0086 D3): quién es el propietario de este conjunto entre actualizaciones."
2337+
helpText: "Quién es el propietario de este conjunto: Package indica que se distribuye con un paquete y que las actualizaciones del paquete lo modifican; Platform y User indican que se creó en este entorno y que las actualizaciones no lo tocan."
23382338
},
23392339
packageId: {
23402340
label: "ID de paquete",
2341-
helpText: "Id del paquete propietario de un conjunto distribuido con un paquete (ADR-0086 D3). Déjalo vacío para un conjunto creado en el entorno."
2341+
helpText: "El paquete que distribuye este conjunto; un valor que nombra otro paquete se rechaza. Déjalo vacío para un conjunto creado en este entorno."
23422342
},
23432343
systemPermissions: {
23442344
label: "Permisos del sistema",
23452345
helpText: "Lista de claves de capacidades del sistema"
23462346
},
23472347
adminScope: {
23482348
label: "Ámbito de administración delegada",
2349-
helpText: "Administración delegada (ADR-0090 D12): permite a quienes tienen este conjunto administrar un subárbol de unidades de negocio. businessUnit es la raíz del subárbol (sys_business_unit.name), es obligatorio y no puede estar en blanco; includeSubtree vale true por defecto; manageAssignments vale false por defecto y permite al titular asignar personas a puestos, y conceder conjuntos directamente, dentro de ese subárbol; un delegado solo puede asignar los conjuntos nombrados en assignablePermissionSets. Déjalo vacío en un conjunto que no delega nada."
2349+
helpText: "Administración delegada: permite a quienes tienen este conjunto administrar un subárbol de unidades de negocio. businessUnit es la raíz del subárbol (sys_business_unit.name), es obligatorio y no puede estar en blanco; includeSubtree vale true por defecto; manageAssignments vale false por defecto y permite al titular asignar personas a puestos, y conceder conjuntos directamente, dentro de ese subárbol; un delegado solo puede asignar los conjuntos nombrados en assignablePermissionSets. Déjalo vacío en un conjunto que no delega nada."
23502350
},
23512351
objects: {
23522352
label: "Permisos de objeto",
@@ -2391,7 +2391,7 @@ export const esESMetadataForms: NonNullable<TranslationData['metadataForms']> =
23912391
},
23922392
delegatable: {
23932393
label: "Delegable",
2394-
helpText: "Quienes la ocupan pueden delegar esta posición por sí mismos, con un plazo y un motivo (ADR-0091 D3). false por defecto: la delegación es solo para administradores."
2394+
helpText: "Quienes la ocupan pueden delegar esta posición por sí mismos, con un plazo y un motivo. false por defecto: la delegación es solo para administradores."
23952395
}
23962396
}
23972397
},

‎packages/platform-objects/src/apps/translations/ja-JP.metadata-forms.generated.ts‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,7 @@ export const jaJPMetadataForms: NonNullable<TranslationData['metadataForms']> =
10191019
},
10201020
end_user_controls: {
10211021
label: "エンドユーザー操作",
1022-
description: "このビューでエンドユーザーが行える操作——クイックフィルター、フィルタータブ、可視化切り替え(ADR-0047、Airtable Interface 互換)。"
1022+
description: "このビューでエンドユーザーが行える操作——クイックフィルター、フィルタータブ、可視化切り替え。"
10231023
},
10241024
navigation_sharing: {
10251025
label: "ナビゲーションと共有",
@@ -2330,23 +2330,23 @@ export const jaJPMetadataForms: NonNullable<TranslationData['metadataForms']> =
23302330
},
23312331
isDefault: {
23322332
label: "既定の権限セット",
2333-
helpText: "everyone ポジション向けのアプリ基準です(ADR-0090 D5)。アプリレベルのセットは起動時に自動でバインドされ、パッケージレベルのセットはインストール時に管理者が確認する提案になります。既定は false です。"
2333+
helpText: "組み込みの everyone ポジションを通じて、サインインするすべてのユーザーにこのセットを付与します。アプリ自身が宣言したセットは起動時に付与され、インストールしたパッケージのセットは管理者が Setup で確認する提案になります。高権限を含むセットはこの方法では付与されません。既定は false です。"
23342334
},
23352335
managedBy: {
23362336
label: "管理元",
2337-
helpText: "レコードの由来(ADR-0086 D3)。アップグレードをまたいで、このセットを誰が所有するかを示します。"
2337+
helpText: "このセットの所有者です。Package はパッケージに同梱され、パッケージのアップグレードで更新されることを示します。Platform と User はこの環境で作成され、アップグレードで変更されないことを示します。"
23382338
},
23392339
packageId: {
23402340
label: "所属パッケージ ID",
2341-
helpText: "パッケージ同梱のセットが属するパッケージ id(ADR-0086 D3)。環境側で作成したセットでは空のままにします。"
2341+
helpText: "このセットを同梱しているパッケージです。別のパッケージを指す値は拒否されます。この環境で作成したセットでは空のままにします。"
23422342
},
23432343
systemPermissions: {
23442344
label: "システム権限",
23452345
helpText: "システム機能キーのリスト"
23462346
},
23472347
adminScope: {
23482348
label: "委任管理スコープ",
2349-
helpText: "委任管理(ADR-0090 D12): この権限セットの保持者が 1 つのビジネスユニットのサブツリーを管理できるようにします。businessUnit はサブツリーのルート(sys_business_unit.name)で、必須かつ空白不可です。includeSubtree の既定値は true です。manageAssignments の既定値は false で、有効にすると保持者はそのサブツリー内でユーザーをポジションに割り当て、権限セットを直接付与できます。委任先が付与できるのは assignablePermissionSets に挙げた権限セットだけです。何も委任しない権限セットでは空のままにしてください。"
2349+
helpText: "委任管理: この権限セットの保持者が 1 つのビジネスユニットのサブツリーを管理できるようにします。businessUnit はサブツリーのルート(sys_business_unit.name)で、必須かつ空白不可です。includeSubtree の既定値は true です。manageAssignments の既定値は false で、有効にすると保持者はそのサブツリー内でユーザーをポジションに割り当て、権限セットを直接付与できます。委任先が付与できるのは assignablePermissionSets に挙げた権限セットだけです。何も委任しない権限セットでは空のままにしてください。"
23502350
},
23512351
objects: {
23522352
label: "オブジェクト権限",
@@ -2391,7 +2391,7 @@ export const jaJPMetadataForms: NonNullable<TranslationData['metadataForms']> =
23912391
},
23922392
delegatable: {
23932393
label: "セルフ委任を許可",
2394-
helpText: "保有者が自分でこのポジションを委任できるようにします。期間を区切り、理由の記入が必要です(ADR-0091 D3)。既定は false で、委任は管理者のみです。"
2394+
helpText: "保有者が自分でこのポジションを委任できるようにします。期間を区切り、理由の記入が必要です。既定は false で、委任は管理者のみです。"
23952395
}
23962396
}
23972397
},

0 commit comments

Comments
 (0)