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:134 z.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

claude added 3 commits August 8, 2026 10:11
…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

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 8, 2026 1:05pm

Request Review

@github-actions github-actions Bot added the size/m label Aug 8, 2026
@github-actions

github-actions Bot commented Aug 8, 2026

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 free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants