diff --git a/.changeset/23853-form-help-texts-plain.md b/.changeset/23853-form-help-texts-plain.md new file mode 100644 index 00000000000..a12d9559fb3 --- /dev/null +++ b/.changeset/23853-form-help-texts-plain.md @@ -0,0 +1,14 @@ +--- +'@objectstack/spec': patch +'@objectstack/platform-objects': patch +--- + +Clause-②: no + +Six help texts an administrator reads in Setup no longer carry ADR numbers. On the Permission Sets edit form, +`isDefault`, `managedBy` and `packageId` are rewritten as plain sentences that say what the field does, and +`adminScope` drops its "(ADR-0090 D12)" prefix. On the Positions edit form, `delegatable` drops "(ADR-0091 D3)". +The view form's End-user controls description drops "(ADR-0047, Airtable Interface parity)". + +The ADR references moved to the comments beside the form rows. The generated metadata-forms translations carry +the new wording in en, zh-CN, ja-JP and es-ES. No key, type or accept/refuse result changes. diff --git a/packages/platform-objects/src/apps/setup-copy-vocabulary.test.ts b/packages/platform-objects/src/apps/setup-copy-vocabulary.test.ts index 78f18880f31..bfaecac36c4 100644 --- a/packages/platform-objects/src/apps/setup-copy-vocabulary.test.ts +++ b/packages/platform-objects/src/apps/setup-copy-vocabulary.test.ts @@ -23,9 +23,11 @@ * 2. every leaf of the four committed `objects` bundles; * 3. the type-level `label` / `description` of the four `metadataForms` * bundles — the sentence a Setup metadata page (Positions, Capabilities, - * Permission Sets) shows under its title. Section descriptions and field - * `helpText` of those forms are the spec's form copy and are not judged - * here; + * Permission Sets) shows under its title, plus the six form leaves named + * in `FORM_HELP_LEAVES` (the Permission Sets and Positions help texts and + * the view form's End-user controls description). The other section + * descriptions and field `helpText` of those forms are the spec's form + * copy and are not judged here; * 4. `SETUP_APP` and this package's `SETUP_NAV_CONTRIBUTIONS`, and the * hand-authored `apps.setup` subtree of each locale. * @@ -172,6 +174,55 @@ describe('Setup copy carries no design-record vocabulary', () => { expect(offenders(strings)).toEqual([]); }); + // The help texts an admin reads on Setup's Permission Sets and Positions edit + // forms, and the view form's End-user controls section. Each one carried a + // decision-record reference until the spec form source moved it into the + // comment beside the row; `en` is regenerated from that source, so judging + // the four bundles judges the source too. + const FORM_HELP_LEAVES = [ + ['permission', 'fields', 'isDefault', 'helpText'], + ['permission', 'fields', 'managedBy', 'helpText'], + ['permission', 'fields', 'packageId', 'helpText'], + ['permission', 'fields', 'adminScope', 'helpText'], + ['position', 'fields', 'delegatable', 'helpText'], + ['view', 'sections', 'end_user_controls', 'description'], + ] as const; + + function formHelpLeaves(bundle: unknown, locale: string): Array<[string, string]> { + return FORM_HELP_LEAVES.map((path) => { + const value = path.reduce((node, key) => (node as Record | undefined)?.[key], bundle); + const at = `${locale}.metadataForms.${path.join('.')}`; + expect(value, `${at} is in the population`).toBeTypeOf('string'); + return [at, value as string]; + }); + } + + it.each(Object.keys(FORM_BUNDLES))('the Permission Set, Position and view form help texts of the %s metadataForms bundle', (locale) => { + const strings = formHelpLeaves(FORM_BUNDLES[locale as keyof typeof FORM_BUNDLES], locale); + expect(strings).toHaveLength(FORM_HELP_LEAVES.length); + expect(offenders(strings)).toEqual([]); + }); + + it('the form help-text assertion fires on the prose it replaced', () => { + // Dark leg: the same walk over a bundle carrying the replaced wording must + // name every leaf, so a walk that reaches nothing cannot pass above. + const replaced = { + permission: { fields: { + isDefault: { helpText: 'App baseline for the everyone position (ADR-0090 D5): an app-level set is auto-bound at boot.' }, + managedBy: { helpText: 'Record provenance (ADR-0086 D3): who owns this set across upgrades.' }, + packageId: { helpText: 'Owning package id for a package-shipped set (ADR-0086 D3).' }, + adminScope: { helpText: 'Delegated administration (ADR-0090 D12): lets holders of this set administer one business-unit subtree.' }, + } }, + position: { fields: { + delegatable: { helpText: 'Holders may delegate this position themselves, time-boxed and with a reason (ADR-0091 D3).' }, + } }, + view: { sections: { + end_user_controls: { description: 'What end users can do on this view (ADR-0047, Airtable Interface parity).' }, + } }, + }; + expect(offenders(formHelpLeaves(replaced, 'replaced'))).toHaveLength(FORM_HELP_LEAVES.length); + }); + it('the Setup app, its nav contributions, and every locale\'s apps.setup translations', () => { const strings: Array<[string, string]> = []; copyStrings(SETUP_APP, 'SETUP_APP', strings); 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 195727e98a6..b6f363ec7a1 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 @@ -1012,7 +1012,7 @@ export const enMetadataForms: NonNullable = { }, end_user_controls: { label: "End-user controls", - description: "What end users can do on this view — quick filters, filter tabs, visualization switching (ADR-0047, Airtable Interface parity)." + description: "What end users can do on this view — quick filters, filter tabs, visualization switching." }, navigation_sharing: { label: "Navigation & sharing", @@ -2323,15 +2323,15 @@ export const enMetadataForms: NonNullable = { }, isDefault: { label: "Is Default", - 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." + 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." }, managedBy: { label: "Managed By", - helpText: "Record provenance (ADR-0086 D3): who owns this set across upgrades." + 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." }, packageId: { label: "Package Id", - helpText: "Owning package id for a package-shipped set (ADR-0086 D3). Leave empty for an environment-authored set." + helpText: "The package that ships this set; a value naming any other package is refused. Leave empty for a set created in this environment." }, systemPermissions: { label: "System Permissions", @@ -2339,7 +2339,7 @@ export const enMetadataForms: NonNullable = { }, adminScope: { label: "Admin Scope", - 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." + 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." }, objects: { label: "Objects", @@ -2384,7 +2384,7 @@ export const enMetadataForms: NonNullable = { }, delegatable: { label: "Delegatable", - helpText: "Holders may delegate this position themselves, time-boxed and with a reason (ADR-0091 D3). Default false — delegation is admin-only." + helpText: "Holders may delegate this position themselves, time-boxed and with a reason. Default false — delegation is admin-only." } } }, 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 a4b4dbcfb57..80c827e3580 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 @@ -1012,7 +1012,7 @@ export const esESMetadataForms: NonNullable = }, end_user_controls: { label: "Controles de usuario final", - 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)." + description: "Lo que los usuarios finales pueden hacer en esta vista: filtros rápidos, pestañas de filtro, cambio de visualización." }, navigation_sharing: { label: "Navegación y uso compartido", @@ -2323,15 +2323,15 @@ export const esESMetadataForms: NonNullable = }, isDefault: { label: "Predeterminado", - 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." + 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." }, managedBy: { label: "Gestionado por", - helpText: "Procedencia del registro (ADR-0086 D3): quién es el propietario de este conjunto entre actualizaciones." + 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." }, packageId: { label: "ID de paquete", - 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." + 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." }, systemPermissions: { label: "Permisos del sistema", @@ -2339,7 +2339,7 @@ export const esESMetadataForms: NonNullable = }, adminScope: { label: "Ámbito de administración delegada", - 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." + 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." }, objects: { label: "Permisos de objeto", @@ -2384,7 +2384,7 @@ export const esESMetadataForms: NonNullable = }, delegatable: { label: "Delegable", - 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." + 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." } } }, 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 b4d88e329a7..a8577eaa610 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 @@ -1012,7 +1012,7 @@ export const jaJPMetadataForms: NonNullable = }, end_user_controls: { label: "エンドユーザー操作", - description: "このビューでエンドユーザーが行える操作——クイックフィルター、フィルタータブ、可視化切り替え(ADR-0047、Airtable Interface 互換)。" + description: "このビューでエンドユーザーが行える操作——クイックフィルター、フィルタータブ、可視化切り替え。" }, navigation_sharing: { label: "ナビゲーションと共有", @@ -2323,15 +2323,15 @@ export const jaJPMetadataForms: NonNullable = }, isDefault: { label: "既定の権限セット", - helpText: "everyone ポジション向けのアプリ基準です(ADR-0090 D5)。アプリレベルのセットは起動時に自動でバインドされ、パッケージレベルのセットはインストール時に管理者が確認する提案になります。既定は false です。" + helpText: "組み込みの everyone ポジションを通じて、サインインするすべてのユーザーにこのセットを付与します。アプリ自身が宣言したセットは起動時に付与され、インストールしたパッケージのセットは管理者が Setup で確認する提案になります。高権限を含むセットはこの方法では付与されません。既定は false です。" }, managedBy: { label: "管理元", - helpText: "レコードの由来(ADR-0086 D3)。アップグレードをまたいで、このセットを誰が所有するかを示します。" + helpText: "このセットの所有者です。Package はパッケージに同梱され、パッケージのアップグレードで更新されることを示します。Platform と User はこの環境で作成され、アップグレードで変更されないことを示します。" }, packageId: { label: "所属パッケージ ID", - helpText: "パッケージ同梱のセットが属するパッケージ id(ADR-0086 D3)。環境側で作成したセットでは空のままにします。" + helpText: "このセットを同梱しているパッケージです。別のパッケージを指す値は拒否されます。この環境で作成したセットでは空のままにします。" }, systemPermissions: { label: "システム権限", @@ -2339,7 +2339,7 @@ export const jaJPMetadataForms: NonNullable = }, adminScope: { label: "委任管理スコープ", - helpText: "委任管理(ADR-0090 D12): この権限セットの保持者が 1 つのビジネスユニットのサブツリーを管理できるようにします。businessUnit はサブツリーのルート(sys_business_unit.name)で、必須かつ空白不可です。includeSubtree の既定値は true です。manageAssignments の既定値は false で、有効にすると保持者はそのサブツリー内でユーザーをポジションに割り当て、権限セットを直接付与できます。委任先が付与できるのは assignablePermissionSets に挙げた権限セットだけです。何も委任しない権限セットでは空のままにしてください。" + helpText: "委任管理: この権限セットの保持者が 1 つのビジネスユニットのサブツリーを管理できるようにします。businessUnit はサブツリーのルート(sys_business_unit.name)で、必須かつ空白不可です。includeSubtree の既定値は true です。manageAssignments の既定値は false で、有効にすると保持者はそのサブツリー内でユーザーをポジションに割り当て、権限セットを直接付与できます。委任先が付与できるのは assignablePermissionSets に挙げた権限セットだけです。何も委任しない権限セットでは空のままにしてください。" }, objects: { label: "オブジェクト権限", @@ -2384,7 +2384,7 @@ export const jaJPMetadataForms: NonNullable = }, delegatable: { label: "セルフ委任を許可", - helpText: "保有者が自分でこのポジションを委任できるようにします。期間を区切り、理由の記入が必要です(ADR-0091 D3)。既定は false で、委任は管理者のみです。" + helpText: "保有者が自分でこのポジションを委任できるようにします。期間を区切り、理由の記入が必要です。既定は false で、委任は管理者のみです。" } } }, 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 77a49aaead7..48bc7f4d7c8 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 @@ -1012,7 +1012,7 @@ export const zhCNMetadataForms: NonNullable = }, end_user_controls: { label: "终端用户控制", - description: "终端用户在此视图上可执行的操作——快速筛选、筛选标签页、可视化切换(ADR-0047,对标 Airtable Interface)。" + description: "终端用户在此视图上可执行的操作——快速筛选、筛选标签页、可视化切换。" }, navigation_sharing: { label: "导航与共享", @@ -2323,15 +2323,15 @@ export const zhCNMetadataForms: NonNullable = }, isDefault: { label: "默认权限集", - helpText: "面向 everyone 岗位的应用基线(ADR-0090 D5):应用级权限集在启动时自动绑定;包级权限集则成为安装时由管理员确认的建议。默认 false。" + helpText: "通过内置的 everyone 岗位,把这个权限集授予每一位登录用户。应用自身声明的权限集在启动时授予;已安装包中的权限集则成为一条建议,由管理员在 Setup 中确认。含高权限的权限集不会以这种方式授予。默认 false。" }, managedBy: { label: "归属来源", - helpText: "记录来源(ADR-0086 D3):跨版本升级时由谁拥有这个权限集。" + helpText: "这个权限集归谁所有:Package 表示它随包分发,包升级时会更新它;Platform 和 User 表示它在本环境中创建,升级不会改动它。" }, packageId: { label: "所属包 ID", - helpText: "随包分发的权限集所属的包 id(ADR-0086 D3)。环境内自行编写的权限集留空即可。" + helpText: "分发这个权限集的包;填写其他包的 id 会被拒绝。在本环境中创建的权限集请留空。" }, systemPermissions: { label: "系统权限", @@ -2339,7 +2339,7 @@ export const zhCNMetadataForms: NonNullable = }, adminScope: { label: "委派管理范围", - helpText: "委派管理(ADR-0090 D12):让持有本权限集的人管理一个业务单元子树。businessUnit 是子树的根(sys_business_unit.name),必填且不能为空白;includeSubtree 默认为 true;manageAssignments 默认为 false,开启后持有人可在该子树内把人员分配到岗位、并直接授予权限集;被委派者只能分配 assignablePermissionSets 中列出的权限集。不委派任何管理权的权限集请留空。" + helpText: "委派管理:让持有本权限集的人管理一个业务单元子树。businessUnit 是子树的根(sys_business_unit.name),必填且不能为空白;includeSubtree 默认为 true;manageAssignments 默认为 false,开启后持有人可在该子树内把人员分配到岗位、并直接授予权限集;被委派者只能分配 assignablePermissionSets 中列出的权限集。不委派任何管理权的权限集请留空。" }, objects: { label: "对象权限", @@ -2384,7 +2384,7 @@ export const zhCNMetadataForms: NonNullable = }, delegatable: { label: "可自助委派", - helpText: "持有者可自行委派该岗位,需限定时段并填写理由(ADR-0091 D3)。默认 false——委派仅限管理员。" + helpText: "持有者可自行委派该岗位,需限定时段并填写理由。默认 false——委派仅限管理员。" } } }, diff --git a/packages/spec/src/identity/position.form.ts b/packages/spec/src/identity/position.form.ts index 62270c8d238..31fec422b4f 100644 --- a/packages/spec/src/identity/position.form.ts +++ b/packages/spec/src/identity/position.form.ts @@ -35,8 +35,9 @@ export const positionForm = defineForm({ // #19331 — `delegatable` is declared by PositionSchema and was offered by // no control, so the only door to an ADR-0091 D3 self-service delegation // was the Source tab's free-text JSON. A boolean node takes the boolean - // control; the copy states the gate the runtime actually applies. - { field: 'delegatable', type: 'boolean', colSpan: 1, helpText: 'Holders may delegate this position themselves, time-boxed and with a reason (ADR-0091 D3). Default false — delegation is admin-only.' }, + // control; the copy states the gate the runtime actually applies. The + // decision record (ADR-0091 D3) stays in this comment, out of the help text. + { field: 'delegatable', type: 'boolean', colSpan: 1, helpText: 'Holders may delegate this position themselves, time-boxed and with a reason. Default false — delegation is admin-only.' }, ], }, ], diff --git a/packages/spec/src/security/permission.form.ts b/packages/spec/src/security/permission.form.ts index fd54be6b8e5..b1071413413 100644 --- a/packages/spec/src/security/permission.form.ts +++ b/packages/spec/src/security/permission.form.ts @@ -35,15 +35,26 @@ export const permissionForm = defineForm({ // #19331 — four declared keys had no control, so the only door to any of // them was the Source tab's free-text JSON. `description` is persisted on // sys_permission_set and shown in Setup; the other three are the ADR-0086 - // D3 provenance pair plus the ADR-0090 D5 baseline flag. + // D3 provenance pair plus the ADR-0090 D5 baseline flag. The help texts + // are an admin's words; the decision records stay here: + // - `isDefault` (ADR-0090 D5): an app-level set is auto-bound to the + // built-in `everyone` position at boot, after the high-privilege check; + // a package-level set materializes a `sys_audience_binding_suggestion` + // an admin confirms in Setup. + // - `managedBy` (ADR-0086 D3): `package` rows are re-seeded on upgrade; + // `platform` / `user` rows are environment config package seeding + // never touches. + // - `packageId` (ADR-0086 D3): a value that disagrees with the package + // the set ships in or is saved into is refused + // (`judgePermissionSetOwnerBinding`). { field: 'description', type: 'textarea', colSpan: 2, helpText: 'Human-readable description shown in Setup.' }, - { field: 'isDefault', type: 'boolean', colSpan: 1, 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.' }, - { field: 'managedBy', type: 'select', colSpan: 1, helpText: 'Record provenance (ADR-0086 D3): who owns this set across upgrades.', options: [ + { field: 'isDefault', type: 'boolean', colSpan: 1, 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.' }, + { field: 'managedBy', type: 'select', colSpan: 1, 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.', options: [ { label: 'Package (upgrade-owned metadata)', value: 'package' }, { label: 'Platform (environment config)', value: 'platform' }, { label: 'User (environment config)', value: 'user' }, ] }, - { field: 'packageId', type: 'text', colSpan: 2, helpText: 'Owning package id for a package-shipped set (ADR-0086 D3). Leave empty for an environment-authored set.' }, + { field: 'packageId', type: 'text', colSpan: 2, helpText: 'The package that ships this set; a value naming any other package is refused. Leave empty for a set created in this environment.' }, ], }, { @@ -61,7 +72,7 @@ export const permissionForm = defineForm({ // touch is rewritten. #23488: the help text names the scope's four // live keys only; `manageBindings` and `authorEnvironmentSets` are // retired tombstones, not rights a set can grant. - { field: 'adminScope', widget: 'json', 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.' }, + { field: 'adminScope', widget: 'json', 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.' }, ], }, { diff --git a/packages/spec/src/ui/view.form.ts b/packages/spec/src/ui/view.form.ts index aa84fb4c7de..c3391702c19 100644 --- a/packages/spec/src/ui/view.form.ts +++ b/packages/spec/src/ui/view.form.ts @@ -158,10 +158,12 @@ export const viewForm = defineForm({ // `ListViewSchema` — a form input for an unwritable key is the false-compliant // UI half of a retirement. To put a published page in front of users, author // an app navigation item instead. + // The end-user controls are ADR-0047's Airtable Interface parity surface; + // the record stays in this comment, out of the section description. { name: 'end_user_controls', label: 'End-user controls', - description: 'What end users can do on this view — quick filters, filter tabs, visualization switching (ADR-0047, Airtable Interface parity).', + description: 'What end users can do on this view — quick filters, filter tabs, visualization switching.', collapsible: true, collapsed: true, fields: [