refactor(app-shell): 把 DecisionOutputDef 收敛成 spec 的纯 re-export,并反转 parity pin - #3185
Merged
Merged
Conversation
…port BLOCKED — does not compile against the `@objectstack/spec` version this repo currently resolves (17.0.0-rc.0). Pushed to preserve the prepared change; see objectstack-ai/objectstack#4562 for the dependency decision it waits on. - `DecisionOutputDef` was `extends SpecDecisionOutputDef { required?: boolean }`. The spec adopted `required` (cd6b9f202, schema-pinned by objectstack#4561), so the derivation adds nothing and collapses to `export type DecisionOutputDef = SpecDecisionOutputDef`. - Rewrote the stale interface TSDoc, which still asserted "the spec does not model it yet". - Inverted the parity pin in `spec-symbol-parity.test.ts`: the exclusion set `Exclude<keyof DecisionOutputDef, keyof SpecDecisionOutputDef>` is now `never`, plus an exact-identity assertion. Verified against spec 17.0.0-rc.1 (which does model `required`): app-shell `tsc --noEmit` clean, the new assertions compile, and the old `'required'` assertion correctly fails (TS2344). Against the resolved 17.0.0-rc.0 the collapse fails with TS2339 `Property 'required' does not exist`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012C2cd7tL8QDoZ2QKN3djJ5
…ision-output-collapse
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012C2cd7tL8QDoZ2QKN3djJ5
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
os-zhuang
marked this pull request as ready for review
August 2, 2026 08:27
This was referenced Aug 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes objectstack-ai/objectstack#4562
背景
app-shell 的
DecisionOutputDef一直是一个结构派生,带着 ONE documented divergence:required之所以是本地加的,是因为服务端会强制它(decide()在任何写入前就拒绝空的 required output),而@objectstack/spec当时还没建模这个字段。现在这个前提没了:spec 在 cd6b9f202 采纳了
required,objectstack#4561 把它钉在 schema 层,而本仓在 #3178 升到@objectstack/spec@17.0.0-rc.1之后已经解析到含required的版本。派生因此变成纯冗余。改动(三项,一个 PR)
1. 收敛冗余派生
packages/app-shell/src/utils/decisionOutputParams.ts保留 re-export(而不是让调用方直接 import spec),是因为这个模块是 approval 的 decision outputs 变成 action params 的唯一入口,它的消费者(
useRecordApprovals、DeclaredActionsBar、RecordDetailView)都从这里读类型。2. 修掉过期的模块 TSDoc
原注释仍然断言 "the spec does not model it yet" —— 已经不成立,而且主动误导。这正是 objectstack#4115 那一类失败:下一个 agent 读到这句会把这个 divergence 当成地面真值并在其上继续构建(#2901 就是这么被填了个反的前提)。现已改写为当前事实,并说明
type的闭合枚举收窄仍然是 load-bearing 的(它才是阻止拼错的 picker kind 静默降级成裸 record-id 文本框的东西 —— objectui#2955)。3. 反转 parity pin
packages/app-shell/src/__tests__/spec-symbol-parity.test.ts之前 ——
required是唯一的本地新增:现在 —— 排除集为空,外加一条精确同一性断言:
这就是原注释承诺的 "fails on that day" —— 今天就是那天。
_TypeIsClosed那条保持不变。文件头的计数也从「eighteen plain re-exports + ScreenSpec 和 DecisionOutputDef 各带一处 divergence」更新为「nineteen plain re-exports + ScreenSpec 仍带一处 divergence」。这条 pin 目前不被任何 CI gate 编译。
packages/app-shell/tsconfig.json的exclude含**/*.test.ts,而 CI 的类型 gate 是 turbo 的逐包tsc --noEmit,所以spec-symbol-parity.test.ts里所有Assert< Equal< … > >都从未进入编译单元。实测:往该文件追加type _Probe = Assert< Equal< 1, 2 > >之后pnpm type-check依然 exit 0。这一点已单独记录在 objectui#3181;本 PR 的反转断言要等 #3181 落地后才真正被 CI 强制。在那之前我用一个临时 tsconfig(
include: ["src"]、去掉 test 的 exclude)显式编译验证,证据见下。这也解释了 objectstack#4562 的前提为何写成「parity 测试会在那天失败」—— 它其实永远不会失败。验证(实测输出)
均在 merge 了 origin/main(含 #3178,spec 解析为 17.0.0-rc.1)之后运行。
类型检查
反转后的断言显式编译(绕开 test exclude)
负向对照 —— 旧的
'required'pin 现在必须失败说明反转不是把断言写松了,而是确实反了向。
测试
Lint
(2090 条全是既有 warning,与本 PR 无关。)
spec 符号 guard
changeset gate
影响面
无行为变更。
DecisionOutputDef是本包内部符号(未从src/index.tsre-export,包只有.一个 entry),收敛前后解析出的形状逐键相同,decisionOutputParams()仍然读d.required—— 只是现在读的是 spec 自己的字段。调用方(useRecordApprovals.ts、DeclaredActionsBar.tsx、RecordDetailView.tsx)一行都不用改,已确认没有 ripple。changeset 标
patch(内部类型重构,无 API 变更;按 AGENTS.md 版本号策略,不声明major)。一点顺带的观察
#3178 只升了
@objectstack/spec,@objectstack/client/core/formula/lint仍是17.0.0-rc.0,而它们对 spec 的依赖是精确版本,所以图里现在同时存在两份 spec:这不影响本 PR(app-shell 侧解析到 rc.1,收敛所需的
required在),但对依赖引用同一性的 guard(spec-subschema-parity.test.ts、以及用createRequire解析 spec.d.ts的两处)是潜在隐患。已记录在 objectui#3182,不在本 PR 范围内。备注
分支上第一个 commit(139b9df)的 message 写着 "BLOCKED — does not compile against 17.0.0-rc.0" —— 那是 #3178 合并之前的状态,现已不成立。因为分支已推送且本仓禁止 force-push,该 commit message 原样保留,以此说明。
🤖 Generated with Claude Code