观察类发现(finding,不入队),来自 #6262 / PR #6433 的实施过程(PD #10 )。不是今天用户会撞到的缺陷 ,是一处「声明的可观测面比实际剥离面窄」的漂移,记录下来免得只活在一条代码注释里。
事实
packages/spec/src/data/data-engine.zod.ts:228 起,DroppedFieldsEventSchema.reason 是闭合枚举:
reason: z . enum ( [ 'readonly' , 'readonly_when' ] )
而 #3407 给这个 seam 的定位是通用的 —— 「写路径上被合法剥掉的、调用方提交过的字段」,因为调用方(典型是 flow 的 update_record 步骤)会逐字段汇报成功 ,而库里那一列根本没变(#4632 的二等形状:调用方以为落库了,数据库不同意,服务端日志是唯一痕迹)。#5126 的 strictReadonlyWrites 是同一 seam 的响亮那一半:要么静默可观测,要么整笔拒绝。
PR #6433 在 update 的 multi 分支新增了一次剥离(把派发已裁定「不是主键」的 data.id 从 SET 载荷去掉)。它是 一次调用方提交过的、被引擎合法丢弃的字段,但它既不是 readonly 也不是 readonly_when,所以:
onFieldsDropped 监听器收不到 这次剥离;
strictReadonlyWrites: true 的调用方不会 因此被拒,它仍拿到一个成功返回。
PR #6433 里刻意没有硬塞进那两个值里(那会让 reason 说谎),改为记一条 warn,并把理由写在注释里:扩这个词表是 packages/spec 的改动,有 packages/spec/src/api/batch.zod.ts 与 .../api/protocol.zod.ts 两处协议响应消费者,不该搭引擎修复的车。本 issue 就是那条注释的外化。
为什么标 finding 而不是入队
若将来处理,面在哪
packages/spec/src/data/data-engine.zod.ts —— DroppedFieldsEventSchema.reason 枚举 + 其 describe;
packages/spec/src/api/batch.zod.ts / packages/spec/src/api/protocol.zod.ts —— 三处 droppedFields 响应字段的消费者;
packages/objectql/src/engine.ts —— update 的 reportDroppedFields 调用点(by-id 与 multi 各一组),以及 PR fix(objectql): multi update 的 SET 载荷剥掉非 id 的 data.id (#6262) #6433 新增剥离块里那段「刻意不上报」的注释(改了要一并删);
生成物:packages/spec 的 api-surface / JSON schema 基线随枚举变动重生成。
关联:#3407 (onFieldsDropped 的由来)、#5126 (strictReadonlyWrites)、#4632 (二等形状)、#3042 / #2948 (现有两个 reason)、#6262 / PR #6433 (触发本条的新剥离)。
观察类发现(
finding,不入队),来自 #6262 / PR #6433 的实施过程(PD #10)。不是今天用户会撞到的缺陷,是一处「声明的可观测面比实际剥离面窄」的漂移,记录下来免得只活在一条代码注释里。事实
packages/spec/src/data/data-engine.zod.ts:228起,DroppedFieldsEventSchema.reason是闭合枚举:而
#3407给这个 seam 的定位是通用的 —— 「写路径上被合法剥掉的、调用方提交过的字段」,因为调用方(典型是 flow 的update_record步骤)会逐字段汇报成功,而库里那一列根本没变(#4632 的二等形状:调用方以为落库了,数据库不同意,服务端日志是唯一痕迹)。#5126的strictReadonlyWrites是同一 seam 的响亮那一半:要么静默可观测,要么整笔拒绝。PR #6433 在 update 的 multi 分支新增了一次剥离(把派发已裁定「不是主键」的
data.id从 SET 载荷去掉)。它是一次调用方提交过的、被引擎合法丢弃的字段,但它既不是readonly也不是readonly_when,所以:onFieldsDropped监听器收不到这次剥离;strictReadonlyWrites: true的调用方不会因此被拒,它仍拿到一个成功返回。PR #6433 里刻意没有硬塞进那两个值里(那会让 reason 说谎),改为记一条
warn,并把理由写在注释里:扩这个词表是packages/spec的改动,有packages/spec/src/api/batch.zod.ts与.../api/protocol.zod.ts两处协议响应消费者,不该搭引擎修复的车。本 issue 就是那条注释的外化。为什么标
finding而不是入队data.id(#6262) #6433 之前根本不存在(载荷原样进 SET,那才是data.id是算子对象 +multi: true时,{"$in":[...]}作为普通列进入updateMany的 SET 载荷,写向主键列 #6262 的数据损坏);剥离之后行为是正确的,只是少一路机器可读信号,warn日志在。onFieldsDropped/ 开了strictReadonlyWrites的调用方,且只在「作者把非 id 的东西写进data.id又声明 multi」这一种作者错误上。category+ 具体原因?)以及两处协议响应的兼容,属于需要先想清楚再做的那类,不适合当作一个小修派发。若将来处理,面在哪
packages/spec/src/data/data-engine.zod.ts——DroppedFieldsEventSchema.reason枚举 + 其 describe;packages/spec/src/api/batch.zod.ts/packages/spec/src/api/protocol.zod.ts—— 三处droppedFields响应字段的消费者;packages/objectql/src/engine.ts—— update 的reportDroppedFields调用点(by-id 与 multi 各一组),以及 PR fix(objectql): multi update 的 SET 载荷剥掉非 id 的data.id(#6262) #6433 新增剥离块里那段「刻意不上报」的注释(改了要一并删);packages/spec的 api-surface / JSON schema 基线随枚举变动重生成。关联:#3407(
onFieldsDropped的由来)、#5126(strictReadonlyWrites)、#4632(二等形状)、#3042 / #2948(现有两个 reason)、#6262 / PR #6433(触发本条的新剥离)。