From e8bf2762af2f116366806616e9da582569d40053 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 5 Nov 2026 18:51:50 +0000 Subject: [PATCH 1/2] docs(spec,i18n): stop naming the removed feature_flags settings namespace The kernel barrel and PUBLIC_AUTH_FEATURES docblocks now name a plugin's own settings manifest (env-overridable as OS_{NAMESPACE}_{KEY}) and the PUBLIC_AUTH_FEATURES registry; the SettingsManifestSchema example drops feature_flags; console.settingsHub.subtitle drops "feature flags" in all ten packs, pinned in the console copy test. Co-authored-by: Claude Claude-Session: https://claude.ai/code/session_01L6bhgVugtCCwBs98FeR27P --- .../30282-feature-flags-namespace-text.md | 14 +++++ packages/spec/src/kernel/index.ts | 8 ++- .../spec/src/kernel/public-auth-features.ts | 9 +-- .../spec/src/system/settings-manifest.zod.ts | 2 +- .../console-copy-system-noun-12956.test.ts | 59 +++++++++++++++++++ ui/packages/i18n/src/locales/ar.ts | 2 +- ui/packages/i18n/src/locales/de.ts | 2 +- ui/packages/i18n/src/locales/en.ts | 2 +- ui/packages/i18n/src/locales/es.ts | 2 +- ui/packages/i18n/src/locales/fr.ts | 2 +- ui/packages/i18n/src/locales/ja.ts | 2 +- ui/packages/i18n/src/locales/ko.ts | 2 +- ui/packages/i18n/src/locales/pt.ts | 2 +- ui/packages/i18n/src/locales/ru.ts | 2 +- ui/packages/i18n/src/locales/zh.ts | 2 +- 15 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 .changeset/30282-feature-flags-namespace-text.md diff --git a/.changeset/30282-feature-flags-namespace-text.md b/.changeset/30282-feature-flags-namespace-text.md new file mode 100644 index 00000000000..7986e95b30e --- /dev/null +++ b/.changeset/30282-feature-flags-namespace-text.md @@ -0,0 +1,14 @@ +--- +'@objectstack/spec': patch +'@object-ui/i18n': patch +--- + +docs(spec,i18n): stop naming the removed feature-flags settings page + +Clause-②: no +Metadata-protocol: none + +The `feature_flags` settings namespace and its Setup page were removed from `@objectstack/service-settings` and `@objectstack/platform-objects`. Two shipped texts still pointed at it; both now say what is live. + +- **Settings hub subtitle (`@object-ui/i18n`).** `console.settingsHub.subtitle` no longer promises feature flags, in all ten language packs. English FROM "Configure your system, integrations, and feature flags." TO "Configure your system and integrations."; each other pack drops its own term the same way. No key is added or removed. +- **Spec doc comments (`@objectstack/spec`).** The kernel barrel and `PUBLIC_AUTH_FEATURES` docblocks no longer send readers to a `feature_flags` settings manifest or to `OS_FEATURE_FLAGS_*`. A setting a plugin reads is declared on that plugin's own settings manifest (ADR-0007, env-overridable as `OS_{NAMESPACE}_{KEY}`); capabilities a deployment advertises to clients are the `PUBLIC_AUTH_FEATURES` registry. The `SettingsManifestSchema` docblock (and its generated reference page) gives `mail`, `branding`, `localization` as example namespaces. No schema, type or export changes. diff --git a/packages/spec/src/kernel/index.ts b/packages/spec/src/kernel/index.ts index a0dd3dd36af..fe1876d4c27 100644 --- a/packages/spec/src/kernel/index.ts +++ b/packages/spec/src/kernel/index.ts @@ -17,9 +17,11 @@ export * from './events.zod'; // feature.zod (FeatureFlagSchema / FeatureStrategy / FeatureFlag factory) was // REMOVED per ADR-0056 D8: zero runtime consumers, and its only protocol home — // the static ObjectStackCapabilities.system.features descriptor — was itself -// removed as dead (#3605). Live toggles are the `feature_flags` settings -// manifest (ADR-0007, env-overridable via OS_FEATURE_FLAGS_*) and the -// PUBLIC_AUTH_FEATURES registry (public-auth-features.ts) for auth gates. +// removed as dead (#3605). There is no central feature-flag namespace: a +// setting a plugin reads is declared on that plugin's own settings manifest +// (SettingsManifestSchema, ADR-0007, env-overridable via OS_{NAMESPACE}_{KEY}), +// and the capabilities a deployment advertises to clients are the +// PUBLIC_AUTH_FEATURES registry (public-auth-features.ts). export * from './manifest.zod'; // metadata-customization.zod (MetadataOverlaySchema, FieldChangeSchema, the // three-layer overlay / 3-way-merge protocol) was REMOVED per ADR-0049 diff --git a/packages/spec/src/kernel/public-auth-features.ts b/packages/spec/src/kernel/public-auth-features.ts index 529df9b2e29..c8c0fbcf012 100644 --- a/packages/spec/src/kernel/public-auth-features.ts +++ b/packages/spec/src/kernel/public-auth-features.ts @@ -18,10 +18,11 @@ import type { z } from 'zod'; * where each flag's consumption surface, default semantics, and gated spec * inputs (or exemption rationale) are recorded and CI-enforced. * - * NOT to be confused with runtime rollout toggles — those live on the - * `feature_flags` settings manifest (ADR-0007), not in the spec (the former - * `kernel/feature.zod.ts` `FeatureFlagSchema` was removed as an orphan: zero - * runtime consumers once its dead capabilities-descriptor home went, #3605). + * NOT to be confused with a runtime setting — that is declared on the settings + * manifest of the plugin that reads it (ADR-0007), not in this registry; there + * is no central feature-flag namespace (the former `kernel/feature.zod.ts` + * `FeatureFlagSchema` was removed as an orphan: zero runtime consumers once its + * dead capabilities-descriptor home went, #3605). * This registry classifies the fixed, deployment-level capability flags that * plugin-auth advertises to anonymous clients. * diff --git a/packages/spec/src/system/settings-manifest.zod.ts b/packages/spec/src/system/settings-manifest.zod.ts index 70de2665b7f..b4208596d43 100644 --- a/packages/spec/src/system/settings-manifest.zod.ts +++ b/packages/spec/src/system/settings-manifest.zod.ts @@ -11,7 +11,7 @@ import { ValueDomainSchema } from '../shared/value-domain.zod'; * Settings Manifest Protocol * * Declarative description of a single namespace of platform settings - * (e.g. `mail`, `branding`, `feature_flags`). Modelled on Apple's + * (e.g. `mail`, `branding`, `localization`). Modelled on Apple's * `Settings.bundle/Root.plist` PreferenceSpecifiers — a small, closed * set of specifier types that the system-owned renderer turns into a * uniform Settings page. diff --git a/ui/packages/i18n/src/__tests__/console-copy-system-noun-12956.test.ts b/ui/packages/i18n/src/__tests__/console-copy-system-noun-12956.test.ts index 7d6519e88da..16fd301d8da 100644 --- a/ui/packages/i18n/src/__tests__/console-copy-system-noun-12956.test.ts +++ b/ui/packages/i18n/src/__tests__/console-copy-system-noun-12956.test.ts @@ -67,3 +67,62 @@ describe('console copy names the system the user is in, not the cloud noun (obje expect(SELF_AS_ENVIRONMENT.test('已被环境变量锁定')).toBe(false); }); }); + +/** + * The Settings hub subtitle does not promise feature flags. + * + * The platform has no feature-flag settings page any more: the `feature_flags` + * settings namespace and its Setup entry were removed because none of its + * toggles was read by anything. A subtitle that still listed feature flags + * sent an administrator looking for a page that is gone. + * + * Every shipped pack is enumerated, so a pack added later is held too, and + * each pack's subtitle is checked against every language's term, so a pack + * that copied another pack's phrasing is caught as well. + */ +describe('console.settingsHub.subtitle promises no feature flags in any pack', () => { + /** "Feature flag(s)" in each shipped language, as the packs spelled it. */ + const FEATURE_FLAG_TERMS = [ + /feature[\s-]?flags?/iu, // en, de ("Feature-Flags") + /indicadores? de funcion/iu, // es + /功能开关/u, // zh + /機能フラグ/u, // ja + /기능\s*플래그/u, // ko + /флаг\S* функци/iu, // ru + /indicateurs? de fonctionnalit/iu, // fr + /أعلام الميزات/u, // ar + /sinalizador\S* de recurso/iu, // pt + ]; + + const packs = Object.entries(builtInLocales as Record); + + it('enumerates every shipped pack', () => { + expect(packs.length).toBeGreaterThanOrEqual(10); + }); + + it.each(packs.map(([code]) => code))('%s subtitle names no feature flags', (code) => { + const pack = (builtInLocales as Record)[code]; + const subtitle = resolve(pack, 'console.settingsHub.subtitle'); + expect(typeof subtitle).toBe('string'); + const hits = FEATURE_FLAG_TERMS.filter((term) => term.test(subtitle as string)); + expect(hits).toEqual([]); + }); + + it('each term catches the subtitle wording it retired', () => { + const retired = [ + 'Configure your system, integrations, and feature flags.', + 'Konfigurieren Sie Ihr System, Integrationen und Feature-Flags.', + 'Configure su sistema, las integraciones y los indicadores de funciones.', + '配置系统、集成与功能开关。', + 'システム、連携、機能フラグを設定します。', + '시스템, 연동, 기능 플래그를 구성합니다.', + 'Настройте систему, интеграции и флаги функций.', + 'Configurez votre système, vos intégrations et vos indicateurs de fonctionnalité.', + 'اضبط النظام والتكاملات وأعلام الميزات.', + 'Configure seu sistema, integrações e sinalizadores de recursos.', + ]; + for (const text of retired) { + expect(FEATURE_FLAG_TERMS.some((term) => term.test(text)), text).toBe(true); + } + }); +}); diff --git a/ui/packages/i18n/src/locales/ar.ts b/ui/packages/i18n/src/locales/ar.ts index c2add4c92bc..c45f0740595 100644 --- a/ui/packages/i18n/src/locales/ar.ts +++ b/ui/packages/i18n/src/locales/ar.ts @@ -2043,7 +2043,7 @@ const ar = { savedViewsUnreadable: "هذه القائمة فارغة لأنه تعذّرت قراءتها، لا لأن هذا الكائن ليس لديه عروض محفوظة. أعد المحاولة، وأبلغ عن المشكلة إذا استمرت.", settingsHub: { title: "الإعدادات", - subtitle: "اضبط النظام والتكاملات وأعلام الميزات.", + subtitle: "اضبط النظام والتكاملات.", loadError: "تعذّر تحميل الإعدادات", empty: "لا توجد صفحات إعدادات متاحة بعد. تظهر هنا عندما يوفّرها تطبيق مثبّت.", adminManaged: "يدير المسؤول الإعدادات", diff --git a/ui/packages/i18n/src/locales/de.ts b/ui/packages/i18n/src/locales/de.ts index b9c43ae38d6..fb80a411592 100644 --- a/ui/packages/i18n/src/locales/de.ts +++ b/ui/packages/i18n/src/locales/de.ts @@ -1828,7 +1828,7 @@ const de = { savedViewsUnreadable: "Diese Liste ist leer, weil sie nicht gelesen werden konnte, nicht weil dieses Objekt keine gespeicherten Ansichten hätte. Versuchen Sie es erneut und melden Sie das Problem, wenn es weiterhin auftritt.", settingsHub: { title: "Einstellungen", - subtitle: "Konfigurieren Sie Ihr System, Integrationen und Feature-Flags.", + subtitle: "Konfigurieren Sie Ihr System und Ihre Integrationen.", loadError: "Einstellungen konnten nicht geladen werden", empty: "Noch keine Einstellungsseiten verfügbar. Sie erscheinen hier, sobald eine installierte App sie bereitstellt.", adminManaged: "Einstellungen werden von Ihrem Administrator verwaltet", diff --git a/ui/packages/i18n/src/locales/en.ts b/ui/packages/i18n/src/locales/en.ts index 2b432e11bff..8457d93c9dd 100644 --- a/ui/packages/i18n/src/locales/en.ts +++ b/ui/packages/i18n/src/locales/en.ts @@ -2260,7 +2260,7 @@ const en = { }, settingsHub: { title: 'Settings', - subtitle: 'Configure your system, integrations, and feature flags.', + subtitle: 'Configure your system and integrations.', loadError: 'Failed to load settings', empty: 'No settings pages are available yet. They appear here when an installed app provides them.', adminManaged: 'Settings are managed by your administrator', diff --git a/ui/packages/i18n/src/locales/es.ts b/ui/packages/i18n/src/locales/es.ts index 4e70bd38085..2054f97f76d 100644 --- a/ui/packages/i18n/src/locales/es.ts +++ b/ui/packages/i18n/src/locales/es.ts @@ -1884,7 +1884,7 @@ const es = { savedViewsUnreadable: "Esta lista está vacía porque no se pudo leer, no porque este objeto no tenga vistas guardadas. Inténtalo de nuevo e informa del problema si continúa.", settingsHub: { title: "Configuración", - subtitle: "Configure su sistema, las integraciones y los indicadores de funciones.", + subtitle: "Configure su sistema y sus integraciones.", loadError: "No se pudo cargar la configuración", empty: "Todavía no hay páginas de configuración disponibles. Aparecen aquí cuando una aplicación instalada las proporciona.", adminManaged: "La configuración la gestiona su administrador", diff --git a/ui/packages/i18n/src/locales/fr.ts b/ui/packages/i18n/src/locales/fr.ts index 34e09486782..bec86edd279 100644 --- a/ui/packages/i18n/src/locales/fr.ts +++ b/ui/packages/i18n/src/locales/fr.ts @@ -1880,7 +1880,7 @@ const fr = { savedViewsUnreadable: "Cette liste est vide parce qu’elle n’a pas pu être lue, et non parce que cet objet n’aurait aucune vue enregistrée. Réessayez, et signalez le problème s’il persiste.", settingsHub: { title: "Paramètres", - subtitle: "Configurez votre système, vos intégrations et vos indicateurs de fonctionnalité.", + subtitle: "Configurez votre système et vos intégrations.", loadError: "Échec du chargement des paramètres", empty: "Aucune page de paramètres n'est encore disponible. Elles apparaissent ici lorsqu'une application installée en fournit.", adminManaged: "Les paramètres sont gérés par votre administrateur", diff --git a/ui/packages/i18n/src/locales/ja.ts b/ui/packages/i18n/src/locales/ja.ts index 24176ed28ad..cd0a93f8f21 100644 --- a/ui/packages/i18n/src/locales/ja.ts +++ b/ui/packages/i18n/src/locales/ja.ts @@ -1828,7 +1828,7 @@ const ja = { savedViewsUnreadable: "このリストが空なのは読み取れなかったためであり、このオブジェクトに保存済みビューがないためではありません。再試行し、繰り返し発生する場合は報告してください。", settingsHub: { title: "設定", - subtitle: "システム、連携、機能フラグを設定します。", + subtitle: "システムと連携を設定します。", loadError: "設定の読み込みに失敗しました", empty: "利用できる設定ページはまだありません。インストールされたアプリが設定ページを提供すると、ここに表示されます。", adminManaged: "設定は管理者が管理しています", diff --git a/ui/packages/i18n/src/locales/ko.ts b/ui/packages/i18n/src/locales/ko.ts index 21267948d08..03ff44986f4 100644 --- a/ui/packages/i18n/src/locales/ko.ts +++ b/ui/packages/i18n/src/locales/ko.ts @@ -1828,7 +1828,7 @@ const ko = { savedViewsUnreadable: "이 목록이 비어 있는 것은 읽지 못했기 때문이며, 이 오브젝트에 저장된 보기가 없어서가 아닙니다. 다시 시도하고, 계속 발생하면 문제를 보고하세요.", settingsHub: { title: "설정", - subtitle: "시스템, 연동, 기능 플래그를 구성합니다.", + subtitle: "시스템과 연동을 구성합니다.", loadError: "설정을 불러오지 못했습니다", empty: "아직 사용할 수 있는 설정 페이지가 없습니다. 설치된 앱이 설정 페이지를 제공하면 여기에 표시됩니다.", adminManaged: "설정은 관리자가 관리합니다", diff --git a/ui/packages/i18n/src/locales/pt.ts b/ui/packages/i18n/src/locales/pt.ts index e403efd6df2..084b9c6b69c 100644 --- a/ui/packages/i18n/src/locales/pt.ts +++ b/ui/packages/i18n/src/locales/pt.ts @@ -1879,7 +1879,7 @@ const pt = { savedViewsUnreadable: "Esta lista está vazia porque não pôde ser lida, não porque este objeto não tenha exibições salvas. Tente novamente e relate o problema se ele persistir.", settingsHub: { title: "Configurações", - subtitle: "Configure seu sistema, integrações e sinalizadores de recursos.", + subtitle: "Configure seu sistema e suas integrações.", loadError: "Falha ao carregar as configurações", empty: "Ainda não há páginas de configuração disponíveis. Elas aparecem aqui quando um aplicativo instalado as fornece.", adminManaged: "As configurações são gerenciadas pelo seu administrador", diff --git a/ui/packages/i18n/src/locales/ru.ts b/ui/packages/i18n/src/locales/ru.ts index 00e049aa3b3..d572f55ad56 100644 --- a/ui/packages/i18n/src/locales/ru.ts +++ b/ui/packages/i18n/src/locales/ru.ts @@ -1940,7 +1940,7 @@ const ru = { savedViewsUnreadable: "Список пуст из-за того, что его не удалось прочитать, а не потому, что у этого объекта нет сохранённых представлений. Повторите попытку и сообщите о проблеме, если она повторяется.", settingsHub: { title: "Настройки", - subtitle: "Настройте систему, интеграции и флаги функций.", + subtitle: "Настройте систему и интеграции.", loadError: "Не удалось загрузить настройки", empty: "Страниц настроек пока нет. Они появятся здесь, когда установленное приложение их добавит.", adminManaged: "Настройками управляет администратор", diff --git a/ui/packages/i18n/src/locales/zh.ts b/ui/packages/i18n/src/locales/zh.ts index e9f150c4f97..c6f964b89aa 100644 --- a/ui/packages/i18n/src/locales/zh.ts +++ b/ui/packages/i18n/src/locales/zh.ts @@ -1918,7 +1918,7 @@ const zh = { }, settingsHub: { title: '设置', - subtitle: '配置系统、集成与功能开关。', + subtitle: '配置系统与集成。', loadError: '加载设置失败', empty: '暂无可用的设置页面。已安装的应用提供设置页面后,会显示在这里。', adminManaged: '设置由管理员管理', From f1e4de5bd241aa4f7569580a535089706ce97443 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 5 Nov 2026 19:08:41 +0000 Subject: [PATCH 2/2] docs(spec): regenerate the settings-manifest reference page Co-authored-by: Claude Claude-Session: https://claude.ai/code/session_01L6bhgVugtCCwBs98FeR27P --- content/docs/references/system/settings-manifest.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/docs/references/system/settings-manifest.mdx b/content/docs/references/system/settings-manifest.mdx index d0a8d66252e..48af44ad9ae 100644 --- a/content/docs/references/system/settings-manifest.mdx +++ b/content/docs/references/system/settings-manifest.mdx @@ -1,7 +1,7 @@ --- title: Settings Manifest — System Protocol reference navTitle: Settings Manifest -description: "Declarative description of a single namespace of platform settings (e.g. mail, branding, feature_flags)." +description: "Declarative description of a single namespace of platform settings (e.g. mail, branding, localization)." --- {/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */} @@ -9,7 +9,7 @@ description: "Declarative description of a single namespace of platform settings Settings Manifest Protocol Declarative description of a single namespace of platform settings -(e.g. `mail`, `branding`, `feature_flags`). Modelled on Apple's +(e.g. `mail`, `branding`, `localization`). Modelled on Apple's `Settings.bundle/Root.plist` PreferenceSpecifiers — a small, closed set of specifier types that the system-owned renderer turns into a uniform Settings page.