一句话 packages/spec/src/data/filter.zod.ts 的 FieldReferenceSchema({ $field: '...' },跨字段比较)是声明了、甚至有生产者在产出、但没有任何 SQL 执行层实现 的契约面 —— 三个新实测事实(cloud#1051 的 PR objectstack-ai/cloud#1059 附完整探针输出)把它从「疑似」钉成「确认」,需要 enforce-or-remove 裁决。
三个实测事实 SqlDriver(better-sqlite3)不编译 :{ amount: { $gt: { $field: 'budget' } } } 被编成 where `amount` > ?,$field 对象作为绑定值 传给 sqlite,抛裸 TypeError(无 code/status)—— 在 ADR-0112 / data: unsupported-filter-operator refusal ships without error.code and leaks the [sql-driver] prefix #4436 的 INVALID_FILTER 信封之外 。已知运算符下「值形态编译不了」这条路径没有拒绝臂。全仓唯一实现是内存求值器 :packages/formula 的 matches-filter.ts 正确处理 $field;driver-sql、objectql 零命中(反查词命中正常)。生产者真实存在,不是死键 :packages/formula/src/cel-to-filter.ts 在把 CEL 规则转译为 filter 时会产出 { $field: path }(字段对字段比较)。也就是说一条用 CEL 写的 RLS / 权限规则,只要含字段间比较,产出的 filter 只有内存求值路径能跑 ;一旦被下推到 SQL,撞上事实 1 的裸 TypeError(或 Turso transport 的静默零行,见 cloud#1058)。为什么这不是「删键了事」也不是「补实现了事」——需要裁决的原因 删 (从 spec 摘掉 FieldReferenceSchema):要先回答 cel-to-filter 的字段间比较改产出什么 —— 那是 RLS 语义面;实现 (SqlDriver 编译 $field 为列引用):SQL 上 column-to-column 比较本身平凡,但要同步决定点号关联路径的语义、以及被引用列名的校验边界(cloud#1051 讨论过,放行不校验等于拆护栏);最低限度 (保留声明,SqlDriver 对该形态按 ADR-0112 响亮拒绝):把裸 TypeError 换成 INVALID_FILTER,消除静默半态,但「声明了不实现」的账仍挂着。无论哪个方向,落点横跨 packages/spec + driver-sql + formula,按「共享契约面归 spec 车道」规则打 domain:spec,由 spec 车道 PM 按 liveness 台账流程分诊(疑似 ADR-0049 enforce-or-remove 的标准形状)。
下游现状(消费端已各自止血,不依赖本单) cloud service-ai:已按名拒绝并给出 workaround 提示(cloud#1059); cloud Turso transport 的静默零行:cloud#1058 单独跟踪; 本单是唯一 跟踪「契约面本身怎么办」的地方。 Refs: cloud#1051、cloud#1058、cloud PR #1059 (探针输出)、#4436 / ADR-0112、#1004 (cloud)。
由 identity/cloud 车道 PM 代立并打标(labeling ≠ claiming),本会话不认领。
Generated by Claude Code
一句话
packages/spec/src/data/filter.zod.ts的FieldReferenceSchema({ $field: '...' },跨字段比较)是声明了、甚至有生产者在产出、但没有任何 SQL 执行层实现的契约面 —— 三个新实测事实(cloud#1051 的 PR objectstack-ai/cloud#1059 附完整探针输出)把它从「疑似」钉成「确认」,需要 enforce-or-remove 裁决。三个实测事实
{ amount: { $gt: { $field: 'budget' } } }被编成where `amount` > ?,$field对象作为绑定值传给 sqlite,抛裸TypeError(无code/status)—— 在 ADR-0112 / data: unsupported-filter-operator refusal ships without error.code and leaks the [sql-driver] prefix #4436 的INVALID_FILTER信封之外。已知运算符下「值形态编译不了」这条路径没有拒绝臂。packages/formula的matches-filter.ts正确处理$field;driver-sql、objectql零命中(反查词命中正常)。packages/formula/src/cel-to-filter.ts在把 CEL 规则转译为 filter 时会产出{ $field: path }(字段对字段比较)。也就是说一条用 CEL 写的 RLS / 权限规则,只要含字段间比较,产出的 filter 只有内存求值路径能跑;一旦被下推到 SQL,撞上事实 1 的裸 TypeError(或 Turso transport 的静默零行,见 cloud#1058)。为什么这不是「删键了事」也不是「补实现了事」——需要裁决的原因
FieldReferenceSchema):要先回答 cel-to-filter 的字段间比较改产出什么 —— 那是 RLS 语义面;$field为列引用):SQL 上 column-to-column 比较本身平凡,但要同步决定点号关联路径的语义、以及被引用列名的校验边界(cloud#1051 讨论过,放行不校验等于拆护栏);INVALID_FILTER,消除静默半态,但「声明了不实现」的账仍挂着。无论哪个方向,落点横跨
packages/spec+driver-sql+formula,按「共享契约面归 spec 车道」规则打domain:spec,由 spec 车道 PM 按 liveness 台账流程分诊(疑似 ADR-0049 enforce-or-remove 的标准形状)。下游现状(消费端已各自止血,不依赖本单)
service-ai:已按名拒绝并给出 workaround 提示(cloud#1059);Refs: cloud#1051、cloud#1058、cloud PR #1059(探针输出)、#4436 / ADR-0112、#1004(cloud)。
由 identity/cloud 车道 PM 代立并打标(labeling ≠ claiming),本会话不认领。
Generated by Claude Code