fix(objectql): hook 层用 Logger 契约形状写诊断,不再自带方言 (#5637) - #5780
Merged
Conversation
…al dialect (#5637) The `Logger` contract declares `error(message, error?: Error, meta?)` — the `Error` slot is second, meta third. `hook-binder.ts` and `hook-wrappers.ts` each declared their own four-method logger shape spelling `error` as `(msg, meta?)`, and their call sites put the diagnostic in the `Error` slot accordingly. tsc could not see it (the contract type satisfies the local shape structurally) and `ObjectLogger` hid it at runtime (it dispatches the second argument by shape). The contract's other implementations — `ConsoleLogger`/`JsonLogger` in `@objectstack/observability` — follow the contract literally, so the meta bag landed in the `error` slot and the whole diagnostic disappeared. - Both option interfaces now take `HookDiagnosticsLogger = Pick<Logger, 'debug'|'info'|'warn'|'error'>` from `@objectstack/spec/contracts` (PD #12: no consumer-side dialect). - All four `error(...)` call sites pass meta in the third parameter. The values in hand are a `CelFault` or a `catch` binding of type `unknown`, none of them statically an `Error`, so the `Error` slot stays `undefined`. - `debug`/`info`/`warn` already matched the contract — unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V7WetGmnfoXNn8cLieKKmx
…k-logger-contract-shape
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 13 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
This was referenced Aug 6, 2026
os-zhuang
marked this pull request as ready for review
August 6, 2026 05:51
This was referenced Aug 6, 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 #5637
按分诊/PM 一致裁决的方向 1执行:
packages/objectql的 hook 层不再自带 logger 方言,改用@objectstack/spec/contracts的契约形状(PD #12)。⛔ 未改动 spec 契约(方向 2 未采纳)。改了什么
1. 两处本地 logger 形状 → 契约的
Pickhook-wrappers.ts/hook-binder.ts各自手写的四方法形状删除,改为一个从契约派生的类型别名:取
Pick而不是整个Logger,是因为这一层只调这四个级别(「最小可用面」);完整的Logger无改动即满足它,而生产上注入的两个 logger(ctx.logger/engine.logger)正是完整契约实现。hook-binder直接复用hook-wrappers导出的同一个类型 —— binder 拿到的 logger 原样转交wrapDeclarativeHook,两者的形状必须同源,不能各写各的。2. 四个调用点改为契约参数序
error(msg, undefined, { … })issue 正文点名三个,实际是四个 ——
hook-wrappers.ts的 condition 编译失败诊断是第四个,同缺陷同文件;改类型之后tsc会直接把它顶红(见下方反向验证),所以它不是扩大范围,而是这次修复的必然一环:hook-wrappers.ts[hook] condition formula failed to compile; …(issue 未列)hook-wrappers.ts[hook] handler failed (onError=log; suppressing)hook-wrappers.ts[hook] async handler error (fire-and-forget)hook-binder.ts[hook-binder] failed to bind hook第二参一律留
undefined:四个点手头的值分别是CelFault({ kind, message },不是Error)和catch绑定(类型unknown/any,hook handler 可以 throw 任何东西),没有一个在静态上是真正的Error。它们的 message 本来就在 meta 里,原样保留,所以这次改动不增删任何诊断字段。把 catch 值提升进 Error 位会把每个宿主渲染出来的error从字符串换成{ message, stack }对象 —— 那是另一个决定,不搭这趟车。3.
debug/info/warn与契约签名完全一致((message, meta?)),未改动。兼容性
ObjectLogger是今天所有宿主实际拿到的实现,自 #5575 起三种形状都认((msg, Error)/(msg, meta)/(msg, undefined, meta)),所以第二参undefined渲染出的记录与改动前逐字段相同 —— 对现有部署零行为变化。真正变的是契约的另外两个实现(@objectstack/observability的ConsoleLogger/JsonLogger):它们此前会把 meta 整块吞掉(落进error位 →error.message/error.stack皆undefined,meta本身undefined),现在如实记录。导出类型
BindHooksOptions/WrapDeclarativeOptions的logger字段收窄了,但全仓库(含 examples/apps)除 objectql 自身外没有第二个bindHooksToEngine/wrapDeclarativeHook调用点,包内既有测试传的{ debug, info, warn, error }字面量也仍然满足新类型 —— 全量 typecheck + 全量测试可证。测试
新增
packages/objectql/src/hook-logger-contract-shape.test.ts(5 例)。关键在于用一个忠于契约的 logger stub(三个参数分开记录、不做形状分派)去审这些调用点 —— 正是ObjectLogger的那份宽容让旧缺陷看不见,所以复刻宽容的 stub 什么也测不出来。error位为空、meta 完整落在第三参(hook / object / event / error 等字段逐一toMatchObject)。ObjectLogger(format: 'json',捕获 stderr)必须照常输出全部字段,证明「第二参 undefined 无害」。合并
origin/main(带入 #5760 / #5753 两个同包改动)后重跑全量:门禁(合并后重跑,全绿):
check:nul-bytes(5659 files,无裸控制字节)、check:query-options-erasure(ratchet 84 sites,none new)、check:engine-double-contract(27 pinned / 65 debt / 1 exempt)、check:durability-log-level、check:startup-registry-verdict。反向验证(方向先判后跑)
预判三条,跑完三条全中:
AssertionError: expected { hook: 'audit_task', …(3) } to be undefined等 4 条 —— meta 对象落进了error位,meta为undefined,正是忠于契约的 logger 会丢字段的那一刻。ObjectLogger)保持绿。 这是预期的,不是漏网:ObjectLogger按形状分派,两种参数序都认,所以它天然不是判别器,只是兼容性钉子。照实记下,不假装它会翻转。tsc也一起转红 —— 这是修复新增的类型级防线,改动前并不存在:第 3 条正是这单最实质的收益:方言之所以能存活,就是因为契约类型在结构上满足本地形状(参数少的一方可赋值,
any双向兼容),tsc一句话都不说。换成契约类型之后,同一个错误再写一次会在编译期被顶回来。范围
仅
packages/objectql/src/hook-wrappers.ts、packages/objectql/src/hook-binder.ts+ 同包新增测试 + changeset(patch)。未碰 engine.ts / integrity / lifecycle / spec / observability / core,未碰content/docs/releases/。Generated by Claude Code