Skip to content

[spec] $field 跨字段比较:spec 声明 + cel-to-filter 产出,但无任何 SQL 执行层实现 —— enforce-or-remove 裁决位 #5041

Closed

Description

@claude

一句话

packages/spec/src/data/filter.zod.ts 的 FieldReferenceSchema({ $field: '...' },跨字段比较)是声明了、甚至有生产者在产出、但没有任何 SQL 执行层实现的契约面 —— 三个新实测事实(cloud#1051 的 PR objectstack-ai/cloud#1059 附完整探针输出)把它从「疑似」钉成「确认」,需要 enforce-or-remove 裁决。

三个实测事实

  1. 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 信封之外。已知运算符下「值形态编译不了」这条路径没有拒绝臂。
  2. 全仓唯一实现是内存求值器:packages/formula 的 matches-filter.ts 正确处理 $field;driver-sql、objectql 零命中(反查词命中正常)。
  3. 生产者真实存在,不是死键: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

Activity

  1. added
    bugSomething isn't working
    domain:specDomain lane — seat card indexed by label:pm:seat
    on Aug 4, 2026
  2. added
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Aug 4, 2026
  3. xuyushun441-sys commented on Aug 4, 2026

    @xuyushun441-sys
    Collaborator

    维护者裁决(2026-08-04):C —— 最低限度,响亮拒绝

    1. SqlDriver 对 { $field } 值形态按 ADR-0112 响亮拒绝:裸 TypeError 换成 INVALID_FILTER 信封,报错点名「$field 跨字段比较当前仅内存求值路径(matches-filter)支持,SQL 下推不支持」—— 消除静默半态;
    2. 保留声明:FieldReferenceSchema 不动,JSDoc 补一行执行支持面说明(内存 ✅ / SQL ❌ 响亮拒绝);cel-to-filter 生产者不改;
    3. SQL 列对列实现挂 v18:执行本单时另立 target:v18 能力单跟踪(点号关联路径语义 + 被引用列名校验边界一并在那单议),本单不做实现;
    4. 非破坏性错误形状修正,不占 v17 切版门;Turso 静默零行归 cloud#1058,不在本单。

    执行归 spec 车道队列,排在 v17 门内任务之后按空位派发。


    Generated by Claude Code

  4. added
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Aug 4, 2026
  5. xuyushun441-sys commented on Aug 4, 2026

    @xuyushun441-sys
    Collaborator

    维护者裁决(2026-08-04):C(最低限度),并 CLAIM

    • C 内容:SqlDriver 对 {$field: ...} 值形态按 ADR-0112 响亮拒绝 INVALID_FILTER(信封完整:catalogued code + httpStatus,不再裸 TypeError),消息言明「跨字段比较当前仅内存求值路径支持」;保留 FieldReferenceSchema 声明,JSDoc 补执行支持面注记;SQL 端 column-to-column 实现另立 v18 能力单(实施时由 dev 顺手立,含点号路径语义与列名校验边界两个待决点)。
    • Turso 静默零行归 cloud#1058,不在本单。
    • 会话:session_01Ehu85kbvMcrNTUJjwxvLJ9(spec 车道 PM,派发给 os-dev 实施)
    • 分支:claude/issue-5041-field-ref-loud-reject

    Generated by Claude Code

  6. added a commit that references this issue on Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workingdomain:specDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchpm:queueReady for the PM dispatch loop

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions