在 #5273(PR #5668)修 packages/spec/src/data/hook.zod.ts 的契约注释时发现,PD #10 单独记录。同一条从未兑现的陈述还活在另外三个面上,#5273 的文件面不含它们,故未在那个 PR 里动。
事实(对 origin/main 核实)
packages/objectql/src/engine.ts 全仓只有 5 处 HookContext 生产点,input: { ast } 只出现在两条读路径(4640 / 4773,分别喂 driver.find / findOne)。写路径构造的是 { id, data, options }(5243)与 { id, options }(5705);批量写的行级谓词走引擎内部的 OperationContext.ast(#2982),从不进 hookContext.input。
以下三处仍照旧宣称它在 ctx.input.ast:
skills/objectstack-data/rules/hooks.md:116 —— 「the write events fire on bulk multi:true operations as well — the row-scoping predicate is in ctx.input.ast」
skills/objectstack-data/references/data-hooks.md:61-62 —— 「the write events fire on bulk multi:true operations (the row-scoping predicate is in ctx.input.ast)」
content/docs/api/data-flow.mdx:313 —— 「Bulk writes (multi: true) fire the same … events as single-id writes, with the row-scoping predicate in ctx.input.ast.」
三处都只是顺带提到 input.ast,主句(「批量写触发同名事件、没有 *Many 事件」)本身仍然成立——和 #5273 里那句的结构一模一样。
另外这三处也都没有描述 #5038 之后的按行形状:批量写的 after* 按匹配行派发,每行是单记录形状、input.id 是绑定的。
为什么单独提而不是搭 #5273 的车
#5273 经分诊确定的文件面就是 spec 那一个注释块;skills/** 与 content/docs/** 是另一条车道,同批可能有别的 agent 在改,不搭车以免撞面。
为什么不只是「文档小事」
skills/objectstack-data/ 是 AI 作者写 hook 时实际读的那份规格。照它写出来的 ctx.input.ast 在批量写上恒为 undefined,而这正是文档点名让人去读的字段——#5273 分诊轮的原话是「契约散文对 AI 作者就是规格,假散文即缺陷」。严重程度请分诊轮判,我按发现原样提交。
建议
按 #5273 已落地的措辞对齐三处:删掉 ctx.input.ast 那半句,补一句「批量写不向 hook 暴露谓词;after* 按行派发、input.id 在那里绑定」。真值可直接引 PR #5668 新增的 packages/objectql/src/hook-input-shape-contract.test.ts。
⚠️ content/docs/releases/v16.mdx:185 也带这句,但 releases 是发布态记录,按 CLAUDE.md 不在代码 PR 里改,这里不列为待办。
关联
Blocked-by: #5273
在 #5273(PR #5668)修
packages/spec/src/data/hook.zod.ts的契约注释时发现,PD #10 单独记录。同一条从未兑现的陈述还活在另外三个面上,#5273 的文件面不含它们,故未在那个 PR 里动。事实(对
origin/main核实)packages/objectql/src/engine.ts全仓只有 5 处HookContext生产点,input: { ast }只出现在两条读路径(4640/4773,分别喂driver.find/findOne)。写路径构造的是{ id, data, options }(5243)与{ id, options }(5705);批量写的行级谓词走引擎内部的OperationContext.ast(#2982),从不进hookContext.input。以下三处仍照旧宣称它在
ctx.input.ast:skills/objectstack-data/rules/hooks.md:116—— 「the write events fire on bulkmulti:trueoperations as well — the row-scoping predicate is inctx.input.ast」skills/objectstack-data/references/data-hooks.md:61-62—— 「the write events fire on bulkmulti:trueoperations (the row-scoping predicate is inctx.input.ast)」content/docs/api/data-flow.mdx:313—— 「Bulk writes (multi: true) fire the same … events as single-id writes, with the row-scoping predicate inctx.input.ast.」三处都只是顺带提到
input.ast,主句(「批量写触发同名事件、没有*Many事件」)本身仍然成立——和 #5273 里那句的结构一模一样。另外这三处也都没有描述 #5038 之后的按行形状:批量写的
after*按匹配行派发,每行是单记录形状、input.id是绑定的。为什么单独提而不是搭 #5273 的车
#5273 经分诊确定的文件面就是 spec 那一个注释块;
skills/**与content/docs/**是另一条车道,同批可能有别的 agent 在改,不搭车以免撞面。为什么不只是「文档小事」
skills/objectstack-data/是 AI 作者写 hook 时实际读的那份规格。照它写出来的ctx.input.ast在批量写上恒为undefined,而这正是文档点名让人去读的字段——#5273 分诊轮的原话是「契约散文对 AI 作者就是规格,假散文即缺陷」。严重程度请分诊轮判,我按发现原样提交。建议
按 #5273 已落地的措辞对齐三处:删掉
ctx.input.ast那半句,补一句「批量写不向 hook 暴露谓词;after*按行派发、input.id在那里绑定」。真值可直接引 PR #5668 新增的packages/objectql/src/hook-input-shape-contract.test.ts。content/docs/releases/v16.mdx:185也带这句,但 releases 是发布态记录,按 CLAUDE.md 不在代码 PR 里改,这里不列为待办。关联
HookContext.input的契约注释声明批量写携带input.ast,引擎从不设置它(AST 只在 opCtx 上);同一张表也未描述 #5038 后 after 事件的按行形状 #5273 / PR docs(spec): HookContext.input 契约表改成引擎真正构造的形状 (#5273) #5668(spec 侧那份已修)opCtx.ast的原因)Blocked-by: #5273