Skip to content

Commit 77c203a

Browse files
docs(spec,i18n): stop naming the removed feature_flags settings namespace (#30647)
<!-- claude-projects-attribution: {"github_login":"os-sales"} --> _Requested by **Sales** · [project thread](https://claude.ai/code/project/chan_01D5bWFY3rFzgJcytD5gD4Uu?thread=cmsg_01D5bWFY3rFzgJcytD5gD4UuV5cRafodM2YQHxeDkdiWJM)_ domain:spec#2 · os-sales · session_01L6bhgVugtCCwBs98FeR27P Fixes #30282 Clause-②: no Metadata-protocol: none ## 维护者速读 - 改了什么:设置中心副标题在十种语言里不再提“功能开关”;spec 的三处注释不再指向已删除的 `feature_flags` 设置命名空间。 - 为什么改:该命名空间与其设置页已随 PR #30272 删除,管理员按副标题找不到页面,开发者按注释设 `OS_FEATURE_FLAGS_*` 也不生效。 - 风险与回滚:只改文案与注释,无代码、无 key 增删;回滚即 revert 本 PR。 - 先看:`ui/packages/i18n/src/locales/en.ts`(副标题)、`packages/spec/src/kernel/index.ts`(注释新说法)、`ui/packages/i18n/src/__tests__/console-copy-system-noun-12956.test.ts`(新守卫)。 - 两分钟验证:`cd ui/packages/i18n && pnpm exec vitest run --root ../.. packages/i18n/src/__tests__/console-copy-system-noun-12956.test.ts`,预期 21 条全绿。 - 需要你做的:无,席位落地。 ## What changes **Spec doc comments (`@objectstack/spec`, comments only, no schema/type/export change)** — written from the live code: `builtinSettingsManifests` in `@objectstack/service-settings` carries no `feature_flags` manifest, and `envKeyOf` spells the env override `OS_` + upper-cased `namespace_key`. - `packages/spec/src/kernel/index.ts` (feature.zod removal note) FROM "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." TO "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)." - `packages/spec/src/kernel/public-auth-features.ts` (module docblock) FROM "NOT to be confused with runtime rollout toggles — those live on the `feature_flags` settings manifest (ADR-0007), not in the spec (the former …" TO "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 …" (rest of the sentence unchanged). - `packages/spec/src/system/settings-manifest.zod.ts` (module docblock) FROM "(e.g. `mail`, `branding`, `feature_flags`)" TO "(e.g. `mail`, `branding`, `localization`)" — all three are registered namespaces. - `content/docs/references/system/settings-manifest.mdx` regenerated by `gen:docs` (the only artifact `check:generated` proved stale): frontmatter `description` and body line follow the docblock. **`console.settingsHub.subtitle` (`@object-ui/i18n`), all ten packs; no key added or removed:** | Pack | FROM | TO | |:---|:---|:---| | en | Configure your system, integrations, and feature flags. | Configure your system and integrations. | | de | Konfigurieren Sie Ihr System, Integrationen und Feature-Flags. | Konfigurieren Sie Ihr System und Ihre Integrationen. | | es | Configure su sistema, las integraciones y los indicadores de funciones. | Configure su sistema y sus integraciones. | | fr | Configurez votre système, vos intégrations et vos indicateurs de fonctionnalité. | Configurez votre système et vos intégrations. | | pt | Configure seu sistema, integrações e sinalizadores de recursos. | Configure seu sistema e suas integrações. | | ru | Настройте систему, интеграции и флаги функций. | Настройте систему и интеграции. | | ja | システム、連携、機能フラグを設定します。 | システムと連携を設定します。 | | ko | 시스템, 연동, 기능 플래그를 구성합니다. | 시스템과 연동을 구성합니다. | | zh | 配置系统、集成与功能开关。 | 配置系统与集成。 | | ar | اضبط النظام والتكاملات وأعلام الميزات. | اضبط النظام والتكاملات. | **Pin** — a new top-level `describe` in `ui/packages/i18n/src/__tests__/console-copy-system-noun-12956.test.ts` (the existing console-copy pin that already enumerates `console.settingsHub`): every pack in `builtInLocales` (floor 10) has a string subtitle matching none of the ten languages' feature-flag terms, plus a matcher self-check that each term catches the retired wording. The spec docblocks are comments: no pin owed. **Changeset** — `.changeset/30282-feature-flags-namespace-text.md`: `patch` for `@objectstack/spec` and `@object-ui/i18n` (published, not private), with both declaration lines. ## Verification All readings at head `f1e4de5bd2`, worktree `objectstack-issue-30282`. - `pnpm --filter @objectstack/spec build` → exit 0; `check:generated` → first run named `content/docs/references/**` stale (plus a `check:test-typecheck` "failed without diagnostics" that ran without a heap flag; re-run alone with `NODE_OPTIONS=--max-old-space-size=4096` → OK, ledger held); `gen:docs` → exit 0; re-run `check:generated` → exit 0, "All 14 generated artifacts are up to date". - `pnpm --filter @object-ui/i18n test` → exit 0, Test Files 95 passed, Tests 1460 passed / 13 skipped (`all-locales-key-parity` included). - `pnpm --filter @object-ui/i18n type-check` → exit 0 (after building the `@object-ui/i18n^...` closure). - `node ui/scripts/check-i18n-en-drift.mjs` → exit 0: 1 `en` value changed, 9 pack values followed. - Ablation (pin): `de` subtitle restored to the old wording through `scripts/ablation-replace.mjs` (anchor 1 → 0, blob `fb80a411` → `b9c43ae3`) → the pin went red, 1 failed / 20 passed, `de subtitle names no feature flags` (matched `/feature[\s-]?flags?/iu`); restore: blob after = HEAD blob `fb80a411`, `git diff HEAD` empty. - `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` → 104 families, each run with its exit code recorded; `--ran` → "104 derived, 104 run, 0 NOT-MEASURED, 0 UNRUN" after the prerequisite re-runs below. - `pnpm check:doc-authoring` → exit 0. eslint on the three spec files (`--no-inline-config`) → exit 0; eslint (ui config) on the test and the ten packs → exit 0. <details><summary>Gate families (104) — exit codes</summary> - 103 families exit 0 on their final run. Six first exited 3 (PREREQUISITE NOT MET: unbuilt `@objectstack/formula`, `@objectstack/lint`, `@objectstack/client-react`, `@objectstack/objectql`, full package build) and were re-run after building those closures: `check:doc-formula-expressions` 0, `check:doc-security-posture` 0, spec `check:skill-examples` 0, `check:docs-transcript-drift` 0, `check:lean-entry-closure` 0, `check:dual-build-cjs-loads` 0. - `pnpm --dir ui exec vitest run scripts/` → exit 1 in this worktree: 2 failures, both in `scripts/__tests__/date-only-zone-pins-10183.test.ts` (the forked `FormulaFunctions.dateOnlyZone-10866` control case answers `11:00` for `03:00`). Not this diff: the diff touches neither `packages/formula` nor `ui/packages/core`, and a control worktree at base `aad1603cc2` with only `@objectstack/formula` built passes the same file 29/29, both without and with this branch's patch applied. The red follows this worktree's extra built `ui/` dists, not the source change. CI's run of this family is the verdict. </details> ## Acceptance notes - Acceptance 1: the docblocks now name the live answer (the reading plugin's own settings manifest; `PUBLIC_AUTH_FEATURES` for deployment-advertised capabilities). Acceptance 2: the subtitle drops feature flags in all ten packs. Acceptance 3: PR #30272 merged 2026-11-05T05:47Z. - Every site was measured at `origin/main` `aad1603c` and was where the card said; none had moved or been fixed. - Open PR #30595 (renames `zh.ts` / `pt.ts`, adds a generated `zh-Hant.ts`) had not merged at push time, so the subtitle is edited in today's file shapes; whichever lands second carries the new subtitle onto the other's shape. The pin enumerates `builtInLocales`, so a `zh-Hant` pack that copies the old Chinese wording is caught. - Left as is, outside this card: `packages/spec/src/kernel/customization-package.test.ts` and `packages/spec/src/system/settings-banner-translation.test.ts` use `feature_flags` only as an arbitrary identifier in test fixtures; `packages/spec/CHANGELOG.md` entries naming `OS_FEATURE_FLAGS_*` are release-owned history; `skills/**` is #30275's. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01L6bhgVugtCCwBs98FeR27P --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 6dd2ca5 commit 77c203a

16 files changed

Lines changed: 96 additions & 20 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+
'@object-ui/i18n': patch
4+
---
5+
6+
docs(spec,i18n): stop naming the removed feature-flags settings page
7+
8+
Clause-②: no
9+
Metadata-protocol: none
10+
11+
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.
12+
13+
- **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.
14+
- **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.

‎content/docs/references/system/settings-manifest.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
---
22
title: Settings Manifest — System Protocol reference
33
navTitle: Settings Manifest
4-
description: "Declarative description of a single namespace of platform settings (e.g. mail, branding, feature_flags)."
4+
description: "Declarative description of a single namespace of platform settings (e.g. mail, branding, localization)."
55
---
66

77
{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
88

99
Settings Manifest Protocol
1010

1111
Declarative description of a single namespace of platform settings
12-
(e.g. `mail`, `branding`, `feature_flags`). Modelled on Apple's
12+
(e.g. `mail`, `branding`, `localization`). Modelled on Apple's
1313
`Settings.bundle/Root.plist` PreferenceSpecifiers — a small, closed
1414
set of specifier types that the system-owned renderer turns into a
1515
uniform Settings page.

‎packages/spec/src/kernel/index.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ export * from './events.zod';
1717
// feature.zod (FeatureFlagSchema / FeatureStrategy / FeatureFlag factory) was
1818
// REMOVED per ADR-0056 D8: zero runtime consumers, and its only protocol home —
1919
// the static ObjectStackCapabilities.system.features descriptor — was itself
20-
// removed as dead (#3605). Live toggles are the `feature_flags` settings
21-
// manifest (ADR-0007, env-overridable via OS_FEATURE_FLAGS_*) and the
22-
// PUBLIC_AUTH_FEATURES registry (public-auth-features.ts) for auth gates.
20+
// removed as dead (#3605). There is no central feature-flag namespace: a
21+
// setting a plugin reads is declared on that plugin's own settings manifest
22+
// (SettingsManifestSchema, ADR-0007, env-overridable via OS_{NAMESPACE}_{KEY}),
23+
// and the capabilities a deployment advertises to clients are the
24+
// PUBLIC_AUTH_FEATURES registry (public-auth-features.ts).
2325
export * from './manifest.zod';
2426
// metadata-customization.zod (MetadataOverlaySchema, FieldChangeSchema, the
2527
// three-layer overlay / 3-way-merge protocol) was REMOVED per ADR-0049

‎packages/spec/src/kernel/public-auth-features.ts‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ import type { z } from 'zod';
1818
* where each flag's consumption surface, default semantics, and gated spec
1919
* inputs (or exemption rationale) are recorded and CI-enforced.
2020
*
21-
* NOT to be confused with runtime rollout toggles — those live on the
22-
* `feature_flags` settings manifest (ADR-0007), not in the spec (the former
23-
* `kernel/feature.zod.ts` `FeatureFlagSchema` was removed as an orphan: zero
24-
* runtime consumers once its dead capabilities-descriptor home went, #3605).
21+
* NOT to be confused with a runtime setting — that is declared on the settings
22+
* manifest of the plugin that reads it (ADR-0007), not in this registry; there
23+
* is no central feature-flag namespace (the former `kernel/feature.zod.ts`
24+
* `FeatureFlagSchema` was removed as an orphan: zero runtime consumers once its
25+
* dead capabilities-descriptor home went, #3605).
2526
* This registry classifies the fixed, deployment-level capability flags that
2627
* plugin-auth advertises to anonymous clients.
2728
*

‎packages/spec/src/system/settings-manifest.zod.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { ValueDomainSchema } from '../shared/value-domain.zod';
1111
* Settings Manifest Protocol
1212
*
1313
* Declarative description of a single namespace of platform settings
14-
* (e.g. `mail`, `branding`, `feature_flags`). Modelled on Apple's
14+
* (e.g. `mail`, `branding`, `localization`). Modelled on Apple's
1515
* `Settings.bundle/Root.plist` PreferenceSpecifiers — a small, closed
1616
* set of specifier types that the system-owned renderer turns into a
1717
* uniform Settings page.

‎ui/packages/i18n/src/__tests__/console-copy-system-noun-12956.test.ts‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,62 @@ describe('console copy names the system the user is in, not the cloud noun (obje
6767
expect(SELF_AS_ENVIRONMENT.test('已被环境变量锁定')).toBe(false);
6868
});
6969
});
70+
71+
/**
72+
* The Settings hub subtitle does not promise feature flags.
73+
*
74+
* The platform has no feature-flag settings page any more: the `feature_flags`
75+
* settings namespace and its Setup entry were removed because none of its
76+
* toggles was read by anything. A subtitle that still listed feature flags
77+
* sent an administrator looking for a page that is gone.
78+
*
79+
* Every shipped pack is enumerated, so a pack added later is held too, and
80+
* each pack's subtitle is checked against every language's term, so a pack
81+
* that copied another pack's phrasing is caught as well.
82+
*/
83+
describe('console.settingsHub.subtitle promises no feature flags in any pack', () => {
84+
/** "Feature flag(s)" in each shipped language, as the packs spelled it. */
85+
const FEATURE_FLAG_TERMS = [
86+
/feature[\s-]?flags?/iu, // en, de ("Feature-Flags")
87+
/indicadores? de funcion/iu, // es
88+
/功能开关/u, // zh
89+
/機能フラグ/u, // ja
90+
/기능\s*플래그/u, // ko
91+
/флаг\S* функци/iu, // ru
92+
/indicateurs? de fonctionnalit/iu, // fr
93+
/أعلام الميزات/u, // ar
94+
/sinalizador\S* de recurso/iu, // pt
95+
];
96+
97+
const packs = Object.entries(builtInLocales as Record<string, unknown>);
98+
99+
it('enumerates every shipped pack', () => {
100+
expect(packs.length).toBeGreaterThanOrEqual(10);
101+
});
102+
103+
it.each(packs.map(([code]) => code))('%s subtitle names no feature flags', (code) => {
104+
const pack = (builtInLocales as Record<string, unknown>)[code];
105+
const subtitle = resolve(pack, 'console.settingsHub.subtitle');
106+
expect(typeof subtitle).toBe('string');
107+
const hits = FEATURE_FLAG_TERMS.filter((term) => term.test(subtitle as string));
108+
expect(hits).toEqual([]);
109+
});
110+
111+
it('each term catches the subtitle wording it retired', () => {
112+
const retired = [
113+
'Configure your system, integrations, and feature flags.',
114+
'Konfigurieren Sie Ihr System, Integrationen und Feature-Flags.',
115+
'Configure su sistema, las integraciones y los indicadores de funciones.',
116+
'配置系统、集成与功能开关。',
117+
'システム、連携、機能フラグを設定します。',
118+
'시스템, 연동, 기능 플래그를 구성합니다.',
119+
'Настройте систему, интеграции и флаги функций.',
120+
'Configurez votre système, vos intégrations et vos indicateurs de fonctionnalité.',
121+
'اضبط النظام والتكاملات وأعلام الميزات.',
122+
'Configure seu sistema, integrações e sinalizadores de recursos.',
123+
];
124+
for (const text of retired) {
125+
expect(FEATURE_FLAG_TERMS.some((term) => term.test(text)), text).toBe(true);
126+
}
127+
});
128+
});

‎ui/packages/i18n/src/locales/ar.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2043,7 +2043,7 @@ const ar = {
20432043
savedViewsUnreadable: "هذه القائمة فارغة لأنه تعذّرت قراءتها، لا لأن هذا الكائن ليس لديه عروض محفوظة. أعد المحاولة، وأبلغ عن المشكلة إذا استمرت.",
20442044
settingsHub: {
20452045
title: "الإعدادات",
2046-
subtitle: "اضبط النظام والتكاملات وأعلام الميزات.",
2046+
subtitle: "اضبط النظام والتكاملات.",
20472047
loadError: "تعذّر تحميل الإعدادات",
20482048
empty: "لا توجد صفحات إعدادات متاحة بعد. تظهر هنا عندما يوفّرها تطبيق مثبّت.",
20492049
adminManaged: "يدير المسؤول الإعدادات",

‎ui/packages/i18n/src/locales/de.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1828,7 +1828,7 @@ const de = {
18281828
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.",
18291829
settingsHub: {
18301830
title: "Einstellungen",
1831-
subtitle: "Konfigurieren Sie Ihr System, Integrationen und Feature-Flags.",
1831+
subtitle: "Konfigurieren Sie Ihr System und Ihre Integrationen.",
18321832
loadError: "Einstellungen konnten nicht geladen werden",
18331833
empty: "Noch keine Einstellungsseiten verfügbar. Sie erscheinen hier, sobald eine installierte App sie bereitstellt.",
18341834
adminManaged: "Einstellungen werden von Ihrem Administrator verwaltet",

‎ui/packages/i18n/src/locales/en.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2260,7 +2260,7 @@ const en = {
22602260
},
22612261
settingsHub: {
22622262
title: 'Settings',
2263-
subtitle: 'Configure your system, integrations, and feature flags.',
2263+
subtitle: 'Configure your system and integrations.',
22642264
loadError: 'Failed to load settings',
22652265
empty: 'No settings pages are available yet. They appear here when an installed app provides them.',
22662266
adminManaged: 'Settings are managed by your administrator',

‎ui/packages/i18n/src/locales/es.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1884,7 +1884,7 @@ const es = {
18841884
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.",
18851885
settingsHub: {
18861886
title: "Configuración",
1887-
subtitle: "Configure su sistema, las integraciones y los indicadores de funciones.",
1887+
subtitle: "Configure su sistema y sus integraciones.",
18881888
loadError: "No se pudo cargar la configuración",
18891889
empty: "Todavía no hay páginas de configuración disponibles. Aparecen aquí cuando una aplicación instalada las proporciona.",
18901890
adminManaged: "La configuración la gestiona su administrador",

0 commit comments

Comments
 (0)