You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
content/docs/automation/hook-bodies.mdx 的 "Not statically checked: the write set" 一节声称写面完全没有静态检查:
Not checked — write side. Nothing validates which fields your body writes. … no lint can verify they exist. This is an accepted gap with no planned closure
"Check your write targets by hand." —— 已经有 lint 在报了;
"Prefer a flow update_record node … so they get the static checking hook bodies can't." —— 这条建议本身仍然对(flow 是 error,hook 是 advisory),但理由错了:hook body 现在有静态检查,差别是严重级别和覆盖面(字面模式 vs 结构化 fields),不是有无。
现象
content/docs/automation/hook-bodies.mdx的 "Not statically checked: the write set" 一节声称写面完全没有静态检查:自 #4305(
validateHookBodyWrites,已合入 main)起,这段话不成立:hook-body-write-unknown-field会把 L2 hook body 里ctx.input.x = …/Object.assign(ctx.input, {x})/ctx.api.object('y').update({x})三类字面写解析出来,拿去和目标对象声明的字段比对,未知字段带 did-you-mean 告警(advisory,不 gate)。#4344 正在把同一套搬到 action 的ctx.api写面。为什么值得记
这一节的下游建议全是从"没有检查"推出来的,现在读起来会把作者推离真正的工具:
update_recordnode … so they get the static checking hook bodies can't." —— 这条建议本身仍然对(flow 是 error,hook 是 advisory),但理由错了:hook body 现在有静态检查,差别是严重级别和覆盖面(字面模式 vs 结构化fields),不是有无。"declared ≠ enforced" 的镜像:这里是 enforced ≠ declared —— 能力已经交付了,文档还在说没有。作者按文档放弃一个真实存在的护栏,和按文档相信一个不存在的护栏,代价是对称的。
需要改什么
object:'*')因而告警的缺席不等于正确。HookSchemaa structuredwritesdeclaration #3700(结构化writes声明,closed as not planned)仍然是准确的历史,但 "accepted gap with no planned closure" 的结论要撤回 —— 缺口是用另一条路(解析写集)关的,不是没关。update_record的建议,把理由换成 error-vs-advisory + 结构化 vs 字面。ctx.api写面。边界
ctx.record那一半不属于本 issue:那是 #4345(所有写都被丢弃,不分声没声明),已在同名 PR 里连同本文件的 sandbox-surface 表和 signature-conventions 一起处理了。本 issue 只针对"未知字段写"这一族的文档描述。参考
content/docs/automation/hook-bodies.mdx"Not statically checked: the write set"packages/lint/src/validate-hook-body-writes.ts(feat(lint,spec): L2 hook body 写不存在字段从 accepted gap 变为作者时 lint 告警 (#4271) #4305)