feat(objectql,runtime): 默认 runner setter 改为 first-wins —— 私有字段探测全数退场 (#4251) - #4398
Merged
Conversation
…ivate-field probes are gone (#4251) setDefaultBodyRunner / setDefaultActionRunner now enforce their own documented contract -- "the runtime layer sets this once per engine" -- by keeping the first runner and returning false for any later call. Public accessors getDefaultBodyRunner() / getDefaultActionRunner() join them, and the fields become real private members instead of `(this as any)` attachments. Before this the invariant lived in the CALLERS: AppPlugin probed the engine's private _defaultBodyRunner / _defaultActionRunner fields through `any` to avoid clobbering another AppPlugin's runner on a shared kernel -- an invariant owned by every caller and enforced by none, and a private reach a field rename would have broken silently. The engine's own bindHooks fallback and ObjectQLPlugin's authored-action re-sync read the same fields the same way. All three read the public accessors now; the only remaining `_default*` mentions are comments and test doubles. Caller audit before changing semantics: every setter call site either owns a fresh engine (sandbox + hook-binder tests) or wants exactly keep-the-first (AppPlugin) -- nobody replaces a runner on a live engine. void -> boolean is additive; AppPlugin uses it to keep its "Installed default ... runner" log truthful. Pinned in hook-binder tests: a second install is refused end-to-end (the first runner is the one that executes) and the accessors expose what was kept. The app-plugin test that pinned the caller-side guard now pins the new division: setter called unconditionally, log skipped when the engine answers false. Verified: objectql 1464/89, runtime 1001/69 (serial runs; an earlier 6-file cloud-connection FAIL was local vitest concurrency noise beside a parallel spec dts build -- single-file and serial reruns green, and the "22 failures on clean HEAD" scare was a stale metadata-protocol dist, NOT a main regression); objectql + runtime dts builds; eslint clean; ratchet holds 168/36 none new. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 27 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
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.
决策 memo 的 2:runner 幂等收编进引擎。
变更
setDefaultBodyRunner/setDefaultActionRunner现在自己执行自己文档里写的契约("the runtime layer sets this once per engine")——first-wins:保留第一个,后续调用忽略并返回false。配上公开访问器getDefaultBodyRunner()/getDefaultActionRunner(),字段从(this as any)._defaultBodyRunner挂载变成真正的private成员。之前的形状,以及为什么它值得修
不变量住在调用方:AppPlugin 靠
any探引擎私有字段来避免共享 kernel 上互相覆盖 —— 人人持有、无人执行;字段一改名,守卫静默恒 undefined,每个 AppPlugin 都重装。而且读这两个字段的不止它:引擎自己的bindHooksfallback、ObjectQLPlugin 的 authored-action re-sync,三处同样的as any私有伸手。三处现在全走公开访问器;全仓剩下的_default*只在注释和 test double 里。改语义前做了调用方审计:每个 setter 调用点要么持有 fresh engine(sandbox / hook-binder 测试),要么要的恰是 keep-the-first(AppPlugin)—— 没有任何人需要在活引擎上替换 runner。
void → boolean是增量;AppPlugin 用返回值让 "Installed default … runner" 日志保持真实(引擎保留了先前的就不再打)。测试
false时日志跳过。getDefaultActionRunner(),原有直接戳字段的用法保留可用。验证过程里的两个插曲(如实记录)
searchFields/groupBy/aggregations指向不存在的字段时被静默降级(#4226 收口后剩下的三条轴) #4254 conformance 测试在 clean HEAD 上也失败。二分到三个 commit 后发现是本地metadata-protocoldist 过期(测试经它的 dist 走 list path,而该包在本 worktree 从未重建)—— 重建后 89/89 绿。main 没红,是我的误报。验证
objectql1464 / 89、runtime1001 / 69(串行)168/36, none new🤖 Generated with Claude Code