Repository navigation
HookEvent 的枚举注释仍在说批量写把行级谓词「carried in input」—— 与 #5273 同一句假话,在同文件 40 行之外 #5899
Description
Activity
分诊:入队
pm:queue,域domain:spec。落点锚定:
packages/spec/src/data/hook.zod.ts:135-140,origin/main@7adc841逐字核实 —— 「row-scoping predicate carried ininput」原句仍在枚举注释里,而同文件 200 行外的契约表已写着「NOT reachable frominputat all」。文件在packages/spec/**⇒domain:spec(同 #5920 的读法:域跟落点文件走,不跟「这是注释改动」的性质走)。分类理由:具体缺陷 + 落点精确到行 + 真值来源已在 main 上(
hook-input-shape-contract.test.ts的三条钉子,含阳性对照「读路径确实带ast」)⇒ 无需新测,直接可派。正文对 #5668 为何没覆盖到它的考据(git log -L 135,144显示该段最后一次变动是b49ccfdfe/#5306)分诊侧复核认可。同文件协调:
hook.zod.ts无在飞 PR(最近一次触碰是290d944/#5780);#5900 是同一条假话在skills/**那一面,本轮同批入队但文件面不相交,可并行。查重:三仓搜
HookEvent/carried in \input`/hook.zod.ts,命中 #5273(已修的那一半)/ #5670 / #5906(hook context alias 无生产者,另一轴,finding`);无重复入口。本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
归拢证据:同文件
:416-417的 JSDoc 也在指一个不存在的 hook 通道,建议一并记入本单修复面来自 #5720 的实现(PR #5938,docs-only)。本评论只留证据,不改代码 —— #5720 的派发面明确
packages/spec/**零改动,而本单已经在改packages/spec/src/data/hook.zod.ts的注释、且是同一类「注释里的假句」,分两个 PR 碰同一个文件不如折进来。事实(对
origin/main核实)packages/spec/src/data/hook.zod.ts:409-427,session.positions的 JSDoc:* ⚠️ **Descriptive, NOT an authorization input.** A hook may READ this to * describe the caller — forwarding it as the sharing service's evaluation :416 * context (`services.sharing.canEdit(..., { positions })`, the shape both :417 * `content/docs/kernel/runtime-services/` pages teach), tailoring a * message, logging — and nothing more.两处不成立:
-
services.sharing.…在 hook 里拿不到。 这是 [docs] runtime-services 的 hook 示例在教ctx.services—— hook 上下文从来没有这个键,照抄的 hook 会拒掉每一次写入 #5720 的实测结论:HookContext由引擎逐键构造(object/event/input/session/provenance/user/api/transaction/ql,engine.ts五处构造点同构),沙箱buildHookSandboxContext同样不产 —— 没有services键。把旧文档示例的ctx: any换成如实的HookContext后编译,直接TS2339: Property 'services' does not exist on type …。所以一段HookContext.session的 JSDoc 用services.sharing.canEdit(...)举例「hook 可以怎么读 positions」,举的是 hook 做不到的动作 —— 与本单:135-140的carried in input同族(注释是这段的唯一规格,读到哪段随机)。 -
它引的文档形状已经不存在了。 PR docs(kernel): runtime-services 的 hook 示例改教真实通道 —— 去掉不存在的
ctx.services(#5720) #5938 按维护者 2026-08-06 裁定(改教ctx.api,docs-only)改掉了这两页:content/docs/kernel/runtime-services/examples.mdx不再教 hook 调canEdit(共享强制由plugin-sharing的引擎中间件按动词自动执行:update 走canEdit、delete 走canDelete,拒绝抛FORBIDDEN,hook 手查是冗余);hook 示例改用ctx.api.object(…)做业务校验。content/docs/kernel/runtime-services/sharing-service.mdx的 Example 改为由持有该服务的代码调用(契约类型ISharingService),并新增一节写明「Enforcement is automatic — do not re-check it in a hook」。
即
:417的「both pages teach」现在两页都不再那样教;这句在 docs(kernel): runtime-services 的 hook 示例改教真实通道 —— 去掉不存在的ctx.services(#5720) #5938 合入后立刻变成过时引用。
建议改法(仍是纯注释,主张不变)
positions的边界主张(描述性、非授权输入、不得用它自行判权)完全保留,只把举例从「hook 调 service」换成 hook 真实能做的读法,或改成通道中立的措辞;顺带别再把这两页当作该形状的出处。若要保留「转发给 sharing service 作为评估上下文」这个用途,应注明那是持有该服务的代码(插件 / 托管运行时绑定)的调用,不是 hook 的。预计同样不动
.describe()与生成物,但按本单已有结论跑check:generated确认即可。关联
- [docs] runtime-services 的 hook 示例在教
ctx.services—— hook 上下文从来没有这个键,照抄的 hook 会拒掉每一次写入 #5720 / PR docs(kernel): runtime-services 的 hook 示例改教真实通道 —— 去掉不存在的ctx.services(#5720) #5938(hook 侧ctx.services的文档面,已 docs-only 修完;packages/spec/**按派发面未动) - [spec]
check:skill-examples应拒绝 os:check 块内把入参标any—— 标记了却零覆盖的空门 #5943(从 [docs] runtime-services 的 hook 示例在教ctx.services—— hook 上下文从来没有这个键,照抄的 hook 会拒掉每一次写入 #5720 拆出:check:skill-examples禁 os:check 块内入参标any—— 就是让上面那句TS2339一开始就该红的门)
Generated by Claude Code
-
实现 #5670(对齐 skills / content/docs 三处的
ctx.input.ast假句)时核实真值来源,在packages/spec/src/data/hook.zod.ts里发现同一条从未兑现的陈述还剩一处。PD #10 单独记录,不在 #5670 的 PR 里顺手改(那单派发面明确排除packages/spec/**,理由是「#5273 已修」——实测只修了其中一处)。事实(对
origin/main=5c94f833c核实)HookEvent枚举的写事件注释:packages/spec/src/data/hook.zod.ts:135-140「row-scoping predicate carried in
input」是假的,和 #5273 删掉的那句是同一条陈述,只是没写.ast后缀。引擎从不在写路径的HookContext.input上放谓词;它在引擎内部OperationContext.ast(#2982)。为什么 #5668 没覆盖到它
PR #5668(#5273 的落地)改的是同文件下方约 200 行的
HookContextSchema.input那段契约表,并在:340起写下了正确措辞:git log -L 135,144:packages/spec/src/data/hook.zod.ts显示这段枚举注释最后一次变动是b49ccfdfe(#5306),#5668 未触及。于是同一个文件现在自相矛盾:枚举注释说谓词在input,200 行外的契约表说它「NOT reachable frominputat all」。真值来源(已在 main 上,无需新测)
packages/objectql/src/hook-input-shape-contract.test.ts—— PR #5668 新增。本次实测全绿(11/11),其中直接钉死本句的三条:阳性对照(读路径确实带
ast)同批为绿,所以「写路径input上没有谓词」是一次测量,不是空过。为什么不是「注释小事」
和 #5273 分诊轮的判断同源:
input是z.record(z.string(), z.unknown()),Zod 对键的存在什么都不校验,所以这段散文就是作者(人或 AI)能读到的唯一规格。一个枚举注释与同文件契约表互相矛盾时,读到哪一段是随机的。建议
把
carried ininput`` 改成与:340那段已落地措辞一致的说法(谓词不在 `input`,在引擎内部 `OperationContext.ast`),主句(批量写触发同名事件、没有 `*Many` 事件)保留。纯注释订正,`.describe()` 未涉及,预计不动生成物 —— 但按 AGENTS.md 需跑 `check:generated` 确认。关联
HookContext.input的契约注释声明批量写携带input.ast,引擎从不设置它(AST 只在 opCtx 上);同一张表也未描述 #5038 后 after 事件的按行形状 #5273 / PR docs(spec): HookContext.input 契约表改成引擎真正构造的形状 (#5273) #5668(同文件契约表那份已修)、hooks 技能与 API 文档仍在教「批量写的行级谓词在ctx.input.ast」——与 #5273 同一句假话,只是另外三个面 #5670(skills 与 content/docs 三个面)opCtx.ast的原因)、Hook event taxonomy is over-specified: collapse 18 events → 8, make findOne fire find hooks, formalize bulk semantics #3195(为什么没有*Many事件)Generated by Claude Code