Skip to content

fix(platform-objects): drop the never-implemented runtime option from sys_setting.scope (#6036) - #6700

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-6036-drop-runtime-scope-option
Aug 8, 2026
Merged

fix(platform-objects): drop the never-implemented runtime option from sys_setting.scope (#6036)#6700
os-zhuang merged 3 commits into
mainfrom
claude/issue-6036-drop-runtime-scope-option

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes#6036

结论:前提成立,按裁决走 remove 路线

sys_setting.scope 声明了四个 cascade 层,平台自始至终只有三个。删掉 { label: 'Runtime', value: 'runtime' },让对象定义的值域回到与 SpecifierScopeSchema 一致。不实现 runtime scope,不改 spec 枚举 —— SpecifierScopeSchema 是对照基准,保持原样。

前提复核(origin/main @ e6025e9,worktree 内重验)

三处证据,方向一致:

位置事实
packages/spec/src/system/settings-manifest.zod.ts:134z.enum(['global', 'tenant', 'user']) —— 三值
packages/services/service-settings/src/'runtime'零命中;scopeRank() 的 switch 只有 global/tenant/user,其余落 default: 99
packages/platform-objects/.../sys-setting-audit.object.ts:72姊妹审计对象的 scope本来就只声明三个 —— 反向佐证 sys_setting 那第四个是孤儿

写入侧闭环:setMany() 的 scope 取自 reg.scopes.get(key),而 reg.scopes 由 manifest 构造(spec.scope ?? manifest.scope ?? 'tenant'),值域就是上面那个三元枚举 —— 没有任何服务路径能产出一行 scope='runtime'。sibling repo 也已扫过:objectui 零命中,cloud 唯一命中是 onboarding 保留 slug 名单(无关)。

存量行实测 —— 这是本次删除的门(不取推断)

按 findings-triage 常设注记:「零写入路径」是预测,预测不是测量。用 @objectstack/verifybootStack(showcaseStack) 起真引擎(真 platform objects + 真 SettingsService + 真 REST 路由),刻意跑在 origin/main 的 pristine 对象定义上(runtime 仍声明),免得本 PR 的删除把答案遮掉:

A. after boot+seed rows=0 dist={}
PUT /api/settings/branding -> 200
PUT /api/settings/localization -> 200
PUT /api/settings/feature_flags -> 200
PUT /api/settings/auth -> 200
B. after real writes rows=4 dist={"tenant":3,"global":1}
==> stored rows with scope="runtime": 0
C. instrument check rows=5 dist={"tenant":3,"global":1,"runtime":1} runtime=1

C 段是仪器阳性对照,是这次测量能成立的关键:直接经 engine 以 system 身份塞一行 scope='runtime',查询确实看得见它。没有 C,B 段的 0 无法区分「平台产不出这种行」和「这条查询什么都查不到」—— 有了 C,0 只剩前一种读法。测量脚本是一次性的,不入库。

反向验证(方向为「红」,预判先行)

git checkout origin/main -- <path> 把修复取出来(⛔ 不用 git stash —— 该栈是全 worktree 共享的)。预判:5 条新 case 里 4 红 1 绿(只有 defaultValue 那条与选项集无关,应保持绿)。实测 4 failed / 276 passed,条数与身份完全吻合:

FAIL sys_setting.scope — value domain (#6036) > agrees with the audit trail object, which records the same layers
AssertionError: expected [ 'global', 'tenant', 'user' ] to deeply equal [ 'global', 'tenant', 'user', …(1) ]
- "runtime",

测试落点:pin 的是 parity,不是手抄字面量

新增 sys-setting.scope-options.test.ts(5 case)。承重的一条把对象的选项集直接与 SpecifierScopeSchema.options 集合比对,而不是比一个两边都要手改的字面量数组 —— 于是将来任一侧单独长出第四层,都会以红测试落地,而不是第二次静默分歧。另有一条单独钉「不含 runtime」:该选项本来就是惰性的,重新加回去在运行时不会坏任何东西,不单列就会第二次顺利通过 review。

其余落点

  • i18n 生成包:四语的 sys_setting.fields.scope.options 各带一条 runtime 标签(en "Runtime" / zh-CN "运行时" / ja-JP "ランタイム" / es-ES "Tiempo de ejecución"),经 node scripts/check-i18n-bundles.mjs --write 重生成,diff 就是各删一行,无其他漂移。
  • content/docs/references/** 未被触发 —— 该目录由 spec 的 build-docs.ts 生成,不读平台对象定义;check:generated 全绿未要求重生成。文档侧「六层 cascade 含 runtime」那处已由 PR docs(protocol): 按 SettingsService 真实契约重写 config-resolution(#5888) #6031 改正为五层(已复核,未重做)。
  • 对象顶部那段五层 resolution-order 注释本就不含 runtime,无需改动(已复核)。

验证

  • pnpm --filter @objectstack/platform-objects test280 passed (10 files);@objectstack/service-settings339 passed (17 files)
  • turbo run typecheck --filter='./packages/*' --filter='./packages/*/*' --filter='./apps/*'120/120 successful
  • .github/workflows/lint.yml逐条枚举执行两个 job 的全部 check:*(含合并后新增的 check:app-nav-i18ncheck:kernel-hook-pairs)+ pnpm lint → 全 PASS;check:type-check-debt exit 0(none above its recorded number)
  • 已合入 mainb127c8b22,合并后重跑 i18n 重生成 → 无漂移

Generated by Claude Code

…om sys_setting.scope (#6036)
`sys_setting.scope` declared four cascade layers while the platform only ever
had three. `SpecifierScopeSchema` is `z.enum(['global','tenant','user'])`,
`SettingsService` never mentions `'runtime'`, and its `scopeRank()` switch
handles only those three — so no code path could write such a row and none
could read one back. The sibling `sys_setting_audit.scope` already declared
only three.
Removed rather than implemented (ADR-0049 enforce-or-remove, remove route).
A new pin compares the object's option list against `SpecifierScopeSchema`
directly, so a future divergence in either direction lands as a red test.
Gated on a measurement, not the zero-write-path prediction: a real engine
booted over the platform objects and driven through `/api/settings/:namespace`
stored 4 rows (tenant 3, global 1) and 0 with `scope='runtime'`, with a
positive control proving the query surfaces such a row when injected.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6bLax4KMrSfnE1ydFU8Dw
@vercel

vercelBot commented Aug 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 8, 2026 1:05pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/platform-objects.

2 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/plugins/packages.mdx(via @objectstack/platform-objects)
  • content/docs/ui/setup-app.mdx(via @objectstack/platform-objects)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sys_setting.scope 声明了 runtime 选项,但 spec 枚举与 SettingsService 都不认它

2 participants

@os-zhuang@claude