Repository navigation
fix(service-settings): the settings manifest list serves a sourced select's options, the table the save judges against - #30568
Conversation
…tions, as the namespace read does Claude-Session: https://claude.ai/code/session_01Utp6CZMwT3iajiQDWrXgCn Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Utp6CZMwT3iajiQDWrXgCn Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 2 package(s): 6 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 172 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 7db957c009463b764664ba83afe2cf9f287c65e4 && git checkout 7db957c009463b764664ba83afe2cf9f287c65e4
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 48b3ae6eb7cd234dcdea467fb55dd493a56bb0c2 1b5ca0e23ff6d92a22922e4b665184b0dabf9049 && git checkout -B drift-repro 48b3ae6eb7cd234dcdea467fb55dd493a56bb0c2 && git merge --no-ff 1b5ca0e23ff6d92a22922e4b665184b0dabf9049
node scripts/docs-audit/affected-docs.mjs --json 48b3ae6eb7cd234dcdea467fb55dd493a56bb0c2
|
|
domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF 维护者速读
席位意见:ACCEPT(#30455)。设置清单列表上的语言下拉,现在和保存时认可的语言是同一张表。 席位核对Head-sha:
|
Requested by Bill · project thread
domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF
维护者速读
GET /api/settings,以及服务内的getManifest/listManifests)现在给「默认语言」这类由运行时来源决定选项的下拉框,返回和单个命名空间页面、和保存校验同一份选项(部署实际支持的语言),不再返回清单里写死的四种;spec 的说明同步写明这个例外。Clause-②: no):保存接受什么、拒绝什么一点没变,只是清单如实说出来;没有 i18n 服务的组合仍返回原来四种;登记的清单对象本身不被改动。回滚即撤本 PR。packages/services/service-settings/src/settings-service.ts里getManifest/listManifests改为走servedManifest的两处;settings-routes.ts清单路由传请求语言的一行;packages/spec/src/system/settings-manifest.zod.ts中valueDomain说明新加的一段。pnpm --filter @objectstack/service-settings exec vitest run --maxWorkers=2 src/localization-locale-options.test.ts,预期 15 条全绿,其中「the manifest list serves the table the namespace read serves and the save judges against」一条。Fixes #30455
Clause-②: no — the manifest list now states the table the save already enforces; nothing a caller sends is refused differently.
Metadata-protocol: none
What changes
One resolution for every manifest read (
settings-service.ts). PR #30446 addedservedManifest, which replaces a sourced key'soptionswith its option source's answer, and only the namespace read (getNamespace,GET /api/settings/:namespace) went through it.getManifest()andlistManifests()returned the registered manifest, soGET /api/settingsservedlocalization.locale's declared four (en-US,zh-CN,ja-JP,es-ES) while the save judged the i18n service's list.getManifest(namespace, display?)andlistManifests(ctx?, display?)now returnservedManifest(reg, namespace, {}, display): no values in effect are passed, so the source answers the options a write is judged against (no stored-value spelling or "no longer offered" entry, which belong to a page). A namespace with no source, or a source with no answer, is returned as the registered object itself, unchanged identity.displayargument is optional; existing callers (localization-currency-lock.ts,cloud-connectionruntime-config-plugin.ts,plugin-securityupgrade-impact-report.ts) compile and behave as before for every unsourced namespace.GET /api/settingspasses the request's language (requestLocaleOf, the namespace read's helper), one line.SettingsOptionSource's docblock (settings-service.types.ts) names the manifest reads among the moments a source is asked.Spec (
packages/spec/src/system/settings-manifest.zod.ts, TSDoc only). ThevalueDomaindocblock said a select withoutvalueDomainkeepsoptionsas its exhaustive save boundary. It now names the runtime option source as the other boundary mover: where a source answers, its options are what a write is judged against and what every manifest read serves; the declaredoptionsare the fallback; it is a runtime registration, not an authorable key. No.describe()string changed, so no generated artifact moved (check:generated: 14 of 14 up to date after a spec build).Tests
localization-locale-options.test.ts(realLiteKernelboot, real settings routes), one new case and one adjusted:['en', 'zh-CN', 'fr-FR', 'vi-VN']andfr-FRin effect,GET /api/settings'slocalization.localeoptions equal the namespace read's served options andgetManifest/ in-processlistManifestsanswer the same; every listed value saves 200, and the declaredja-JPthe list leaves out is refusedinvalid_optionwithconstraint.allowedequal to the listed values.getManifestreturns the declared four while a source answers. It now asserts that once the source has no answer ([]),getManifestis the declared four again, which is what proves the registered manifest was never changed.Ablation through
scripts/ablation-replace.mjs:listManifestsmade to returnreg.manifest⇒ the new case red, 14 others green; restored, blob equal toHEAD,git diff HEADempty.Acceptance notes
getManifestis now a served read like the namespace read. No caller in the tree needs the declared table from it: the one in-package caller (registerLocalizationCurrencyLock) only probes that the namespace exists.listManifestsasks each namespace's sources before the permission filter; onlylocalization.localehas one today, and a source is a synchronous in-memory read.Verification
All at head
1b5ca0e2(the branch withorigin/main86ae2ca merged), afterpnpm install --frozen-lockfile(exit 0) and a full build (turbo run build --filter='!@objectstack/docs', 119/119, under the verify lock):pnpm --filter @objectstack/service-settings test: 69 files, 1172 passed;typecheck: exit 0 (both before the merge; the merged commits touch neither this package nor its dependencies' sources this diff reads).pnpm --filter @objectstack/spec buildexit 0, thencheck:generated: 14 of 14 artifacts up to date.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 83 families from the change set; each run with its exit recorded before any pipe: 83 of 83 exit 0.--ran: 83 derived, 83 run, 0 NOT-MEASURED, exit 0.pnpm lint: exit 0.!andClause-②carries no(narrowing)arm.Generated by Claude Code