Repository navigation
fix(service-settings)!: remove the Feature Flags page whose four toggles changed nothing - #30272
Conversation
… toggles had no reader The four toggles of the feature_flags settings namespace (ai_enabled, kanban_swimlanes, realtime_cursors, inline_comments) were read by no code, so saving one changed nothing (ADR-0049 enforce-or-remove). Removing them leaves the page empty, so the namespace goes too: its manifest, the featureFlagsSettingsManifest export, its entry in builtinSettingsManifests, its translations, the Setup nav entry with its locale labels and source hashes, and the texts that name it. A pin holds that the namespace is no longer registered. Claude-Session: https://claude.ai/code/session_01Utp6CZJQ8AFU2wk2a8fuhz Co-authored-by: Claude <noreply@anthropic.com>
… to 9 Claude-Session: https://claude.ai/code/session_01Utp6CZJQ8AFU2wk2a8fuhz Co-authored-by: Claude <noreply@anthropic.com>
…the ADR-0087 gate reads Claude-Session: https://claude.ai/code/session_01Utp6CZJQ8AFU2wk2a8fuhz Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 6 package(s): 14 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 5 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 61 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 02f084bf16ccb44db778d972e6ead6eb1bfaa291 && git checkout 02f084bf16ccb44db778d972e6ead6eb1bfaa291
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 959c26be1f4179202b0ed42f58076190d4d590d5 74c2ef82638a525260943246260fcd7f2fd6902a && git checkout -B drift-repro 959c26be1f4179202b0ed42f58076190d4d590d5 && git merge --no-ff 74c2ef82638a525260943246260fcd7f2fd6902a
node scripts/docs-audit/affected-docs.mjs --json 959c26be1f4179202b0ed42f58076190d4d590d5
|
|
domain:server#5 · os-bill · session_01Utp6CYVV6fcAQrNTDQRvPb Contract reviewServed-tier: Reviewed at 2026-11-05T04:42Z against card #30204 (body and comments 6648454483, 6648715176, 6649695459), PR #30272 (body, file list, net diff against merge base Check-runs on this head. Success: Governed Surface Queue Guard, Lint · ESLint, Lint · docs & code guards, Lint · scoped · tooling self-tests, Type Check · source gates, Dogfood Regression Gate, Live E2E UI, Test UI, Build Docs, Check Changeset (first run), Check Documentation Links, Flag docs affected by code changes, PR-body guards (both), Plan Test Core shards, Spec property liveness, Auto Label, Check PR Size, filter. Still pending (in_progress, no conclusion): Build Core; Check Changeset (second run — the job that carries ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgmentJudged against the card's ruling ("Remove the four toggles, and the settings page if it is left empty. A flag comes back with the feature that reads it."), ADR-0049 enforce-or-remove, and the code each hunk cites. The premise re-checked on this head:
Must-fix
Should-fix
Implemented-by: VERDICT: FAIL |
…cklist, the sys_setting example and the Setup tree pin Claude-Session: https://claude.ai/code/session_01Utp6CZJQ8AFU2wk2a8fuhz Co-authored-by: Claude <noreply@anthropic.com>
…space that exists, in every locale Claude-Session: https://claude.ai/code/session_01Utp6CZJQ8AFU2wk2a8fuhz Co-authored-by: Claude <noreply@anthropic.com>
|
domain:server#5 · os-bill · session_01Utp6CYVV6fcAQrNTDQRvPb Contract reviewServed-tier: Delta reviewed at 2026-11-05T05:22Z: Check-runs on this head. Every check-run is ① Derived judgments
② Semver levelUnchanged by the delta and still right: ③ Boundary flags
④ Design judgmentJudged against the card's ruling and ADR-0049 as before; the delta changes no behaviour, so the question is whether each hit holds against the code it cites.
Must-fix: none. The previous record's one must-fix is closed in the tree. Should-fix: none new. The two previous should-fix items that remain open ( Implemented-by: VERDICT: PASS |
|
domain:server#5 · os-bill · session_01Utp6CYVV6fcAQrNTDQRvPb 席位核对 · ACCEPT · head
|
| Item | Reading |
|---|---|
| Shape | Ready path: base main, relay pr_create. Body: attribution, signature, ## 维护者速读, Fixes #30204; Clause-②:, Metadata-protocol: and Skills-docs: follow-up #30275 at line start; ## Deviations from the order written by the seat from the dev's draft. |
| Ruling | 「以上都同意,立卡」: the four toggles are removed (none had a reader, ADR-0049 enforce-or-remove), and the page, left empty, is removed with its Setup entry and the featureFlagsSettingsManifest export (seat amendment 03:16Z). getManifest('feature_flags') throws UnknownNamespaceError (SETTINGS_UNKNOWN_NAMESPACE), pinned; stored sys_setting rows and OS_FEATURE_FLAGS_* become inert, said in the body. |
| Contract review (narrowing) | CONTRACT_REVIEW_TIER FAIL at 1d8e7702a (6649883787: one must-fix, platform-core.json still said 11 at :796/:885); delta PASS at 74c2ef82 (6650443923), with the must-fix closed and nothing new. Should-fix 2/3 (spec docblocks, Settings hub subtitle) → #30282; should-fix 4 (sys_setting help example) fixed here. |
| Gates | CI on 74c2ef82: 40 success, 14 skipped, 0 failure, 0 pending (Test Core 1/8, red on the previous head from the Setup tree count, now green). Dev: derived 96/96 exit 0, pnpm lint 0. |
| Declarations | Clause-②: no (narrowing); changesets patch with the BREAKING banner (check-changeset-no-major), ADR-0087 runtime-export-retired disposition (the FROM line names the export; the four keys are listed as removed). Metadata-protocol: none. |
| Escalations | Cloud repo: not readable from this seat (org code search returns objectstack only), as the body states; a cloud reader of feature_flags.* would now get 404 UNKNOWN_NAMESPACE. Main red permission-set-clone-door is #30255 (from #30222), not this PR's. skills/** → #30275. |
| Landing | Not governed (0 of 34 paths), 285 changed lines. Tier S: seat lands, pr_ready + automerge_enable. |
Requested by Bill · project thread
domain:server#5 · os-bill · session_01Utp6CYVV6fcAQrNTDQRvPb
维护者速读
featureFlagsSettingsManifest一起删掉。sys_setting行和OS_FEATURE_FLAGS_*环境变量留在原处、变成无人读取的惰性数据,不做清理;访问/api/settings/feature_flags现在答 404。直接 import 该导出的宿主编译会报错(changeset 写明一行修法)。回滚即撤本 PR,无数据迁移。packages/services/service-settings/src/manifests/index.ts(聚合去掉一项)、packages/platform-objects/src/apps/setup-nav.contributions.ts(导航条目)、packages/services/service-settings/src/settings-service.test.ts的新钉子no longer serves the retired feature_flags namespace。pnpm --filter @objectstack/service-settings exec vitest run src/settings-service.test.ts -t "retired feature_flags",预期 1 条通过;或在控制台 Setup → 配置分组里,预期不再出现「功能开关」。Fixes #30204
Clause-②: no (narrowing) — removes the four settable keys of the
feature_flagssettings namespace, the then-empty namespace, its Setup entry and thefeatureFlagsSettingsManifestexport; nothing is widenedMetadata-protocol: none
Skills-docs: follow-up #30275
What changes
The card's direction, agreed by the maintainer on filing (「以上都同意,立卡」): "Remove the four toggles, and the settings page if it is left empty. A flag comes back with the feature that reads it." Triage 6648454483 asks to wire each flag or remove it and say which per flag.
Per flag: all four removed, none wired. Measured at
origin/main5fa9375e(and re-checked after mergingorigin/mainat 1d8e770): agit grepforai_enabled,kanban_swimlanes,realtime_cursors,inline_commentsoutside tests and docs hits only the manifest and the service-settings translations. No code underpackages/orui/readsfeature_flags.*through the settings service, the settings client or anOS_FEATURE_FLAGS_*variable.ai_enabledAppHeader.tsx'stopbar.aiAssistantis a label key)kanban_swimlanesrealtime_cursorsinline_commentsThe console's
featuresmap (ui/packages/app-shell/src/console/AppContent.tsx) comes from/api/v1/auth/config, not from this namespace, and is untouched. The cloud repository is not readable from this seat, so a reader there is not ruled out; it is said so here and in the report.The namespace goes too. With the four toggles gone the manifest held only a beta banner and two empty groups, so per the ruling the page is removed (seat amendment 03:16Z, Claim 6648715176):
@objectstack/service-settings:manifests/feature-flags.manifest.tsdeleted;builtinSettingsManifestsloses it (10 manifests to 9); thefeatureFlagsSettingsManifestexport leavessrc/manifests/index.tsandsrc/index.ts; thefeature_flagsblock leaves the en / zh-CN / ja-JP / es-ES bundles; README's env-override example moves toai.log_prompts, and its built-in table drops the row; the plugin option's comment namesbuiltinSettingsManifestsinstead of a list.@objectstack/platform-objects: the Setup entrynav_settings_feature_flagsand its four locale labels and three source-hash rows are removed, so Setup leaves no link to a namespace nothing serves.docs/qa/platform-checklist/areas/platform-core.json(11 namespaces to 10, list and variants),packages/cli/README.md,content/docs/protocol/kernel/config-resolution.mdx(env example nowOS_AI_LOG_PROMPTS),content/docs/ui/apps.mdx(Configuration group row), and comment-only lines inplugin-security/src/objects/default-permission-sets.ts,service-datasource/src/admin-routes.tsandmcp/src/connect-ui.ts.What happens to a stored value. Nothing registers
feature_flagsany more, soSettingsService.getManifest('feature_flags')throwsUnknownNamespaceError(SETTINGS_UNKNOWN_NAMESPACE), a read or write through the service rejects the same way, and the REST door answers404 UNKNOWN_NAMESPACE. Asys_settingrow stored under the namespace and anOS_FEATURE_FLAGS_*environment variable are left where they are and become inert: no code resolves them. They are not cleaned up; an operator may delete them at will.The changeset carries the BREAKING banner, both declaration lines, and the ADR-0087 disposition
not-required (runtime-export-retired @objectstack/service-settings#featureFlagsSettingsManifest), verified by the gate (predicates 1 to 3).Tests
settings-service.test.ts,SettingsService — registry: with every built-in manifest registered andOS_FEATURE_FLAGS_AI_ENABLED=truein the env,builtinSettingsManifestscarries nofeature_flags,getManifest('feature_flags')throws anUnknownNamespaceErrorwhosecodeisSETTINGS_UNKNOWN_NAMESPACE, andget('feature_flags', 'ai_enabled')rejects with that code.ai.log_prompts(default false) andai.trace_enabled(default true): env coercion,getNamespace, the option-table negative case, andenvKeyOf.settings-visibility-declaration.pin.test.ts(96 predicates unchanged: the removed manifest declared novisible),settings-retired-workspace-noun.pin.test.tsandsettings-translation-coverage.test.ts.settings-branding-posture.pin.test.ts: the walled-posture listing control keepscompanyandlocalization(the namespace it also named is gone); the Setup-order control now compares againstnav_settings_lifecycle, the last platform-objects entry.settings-help-business-words.pin.test.tssweeps four namespaces instead of five.Suite readings on head 1d8e770 (after merging origin/main)
pnpm --filter @objectstack/service-settings test: Test Files 67 passed (67), Tests 1151 passed (1151);typecheckexit 0.pnpm --filter @objectstack/platform-objects test: Test Files 110 passed (110), Tests 1514 passed (1514);typecheckandcheck:test-typecheckexit 0.Full dogfood (owed by the narrowing arm), head 1d8e770: one red, also red with this diff reverted
pnpm --filter @objectstack/dogfood testunder the verify lock: VERDICT command-exit 1; Test Files 1 failed, 418 passed, 3 skipped (422); Tests 1 failed, 3491 passed, 36 skipped (3528).test/permission-set-clone-door.dogfood.test.ts"a platform set (the lock-and-clone rule's commonest source) copies into its shipping package's pair": the clone ofmember_defaultanswers 422INVALID_METADATA("grants on object 'sys_comment' which is not defined in objects").origin/main(19 files), the five touched packages force-rebuilt, the same file run: the same test fails the same way (1 failed, 10 passed). Restored to HEAD afterwards (git diff HEADempty) and rebuilt. So the red is onmain, not caused by this PR. Thesys_commentgrant onmember_defaultcame in with 490d136 (fix(plugin-security): every member reads and posts comments, and reads the activity history, of the records they can read #30222), before this branch's base.Deviations from the order
docs/qa/platform-checklist/areas/platform-core.jsonstill counted 11 open-framework namespaces in two places (theGET /api/settingsstep and thesettings-hub-roundtripscoring clause); both now say 10, matching the list. Fixed in 8dffea3.packages/platform-objects/src/system/sys-setting.object.tsno longer givesfeature_flagsas an example namespace (nowmail, branding, storage);node scripts/check-i18n-bundles.mjs --writeregenerateden.objects.generated.ts, and the zh-CN / ja-JP / es-ES help strings were updated by hand (merge mode keeps translated values). Fixed in 8dffea3 (source) and 74c2ef8 (bundles).packages/cli/test/connect-agent-both-halves-wire.pin.test.tspins the platform admin's Setup tree; withnav_settings_feature_flagsgone it is 32 entries, not 33 (both assertions, and the comment's 24 contributions now 23). A grep of every test underpackages/andui/fornav_settings_feature_flagsor a Setup entry total found no other pin. Fixed in 8dffea3.runtime-export-retiredcategory reads exactly the marker's operands there. The four keys are listed in prose as removed, each with no effect.Readings on 74c2ef8:
dispatch-gates --commands96 derived (the 95 above pluscheck:cli-test-child-env), 96 exit 0,--ran0 NOT-MEASURED;pnpm lintexit 0; cli unit pins (3 files, 12 tests), platform-objects 1514/1514 + typecheck, plugin-audit / plugin-security nav tests, rest.test.ts 216/216, service-settings setup-nav-hub-parity 9/9, all pass;check:i18nandcheck:i18n-stale-fillexit 0.Acceptance notes
docs/adr/0007-settings-manifest-and-kv-store.mdstill showsfeature_flags.ai_enabledas its worked example; ADRs are outside this PR's surface and the example stands as the record of the decision.skills/objectstack-platform/references/plugin-development.md:354names thefeature_flagsmanifest as the place for org-tunable toggles;skills/**is outside this PR (theSkills-docs:line above), the seat files it.docs.objectos.airepository documentsFEATURE_FLAGS_AI_ENABLED; that text is now false and lives outside this repository.packages/spectests (settings-banner-translation.test.ts,customization-package.test.ts) and the console testSettingsField.infoBanner-12671.test.tsxusefeature_flagsas a self-contained fixture string; none reads the removed manifest, and both trees are outside this PR.docs/audits/2026-06-handwritten-docs-accuracy-followups.md:288cites the old key as an example in a dated audit; left as history.CHANGELOG.mdentries that mentionOS_FEATURE_FLAGS_AI_ENABLEDare release-owned and unchanged.Verification
Derived gates: 95 derived, 95 run, 0 NOT MEASURED
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(31 paths vs merge base) derived 95 families; the list re-derived on head 1d8e770 is identical. Every one exits 0. The sweep ran on a9be523; after the merge, these re-ran on 1d8e770, all exit 0:check-adr-0087-registration --base origin/main(verified:runtime-export-retired @objectstack/service-settings#featureFlagsSettingsManifest),check-plugin-teardown-shape --self-test,spec check:skill-examples,check:dual-build-cjs-loads,check:i18n,check:i18n-stale-fill,check:type-check-coverage,docs-audit/check-affected-docs,check:published-files,check-changeset-no-major,check-empty-changeset,check:nul-bytes, andcheck-platform-checklist --changed-from origin/main(outside the derivation).--ranreconciliation: "95 derived famil(ies) accounted for — 95 run, 0 NOT-MEASURED".Three families first exited 3 (prerequisite not met: a shallow fixture commit, an unbuilt
client, an unbuilt workspace) and went green once the prerequisite was met; the firstcheck-adr-0087-registrationrun was red on the changeset's FROM line and went green after the fix in a9be523.pnpm lint: exit 0 on 1d8e770.Generated by Claude Code