Skip to content

[engine] driver-sql 编译 spec 未声明的「数组 where 方言」—— 与 Turso remote 的拒收分叉,需一次定调(接纳进 spec 或响亮弃用) #5158

Description

@claude

在 cloud#1075(PR objectstack-ai/cloud#1080)的事实核对中查实,cloud 侧 dev 按约束不跨仓,由 cloud 分片 PM 代立。

事实

spec 的 BaseQuerySchema.where 声明为 record(FilterConditionSchema),不含数组方言。但 framework driver-sql 实际编译裸 AST 数组:find([['stage','=','won']]) 产出真实过滤(sql-driver-filter-no-silent-drop.test.ts 只对裸三元组抛错,对数组包裹的三元组是编译,[] 被显式钉成「无过滤」)。

即:driver-sql 在执行一种 spec 未声明的 where 方言。cloud Turso remote 模式在 cloud#1075 之后对同样输入响亮拒收(理由:transport 不该复制未声明方言 —— ADR-0053 D-A1 的第二实现问题),于是同一输入本地编译、远程抛错。

需要 framework 侧一次定调

  • A. spec 接纳数组方言(声明进 where 的 union)→ 两侧都编译,remote 补实现;
  • B. driver-sql 弃用数组方言(带日期的响亮弃用 → 拒收)→ 两侧都拒,消灭未声明方言。

按 declared = enforced 的仓规,B 更顺;但该方言有真实到达记录(filter-no-silent-drop changeset),需要先清点调用方再定。在定调之前,cloud remote 的拒收行为是安全侧的(响亮而非静默全表),不需等待。

Refs: cloud#1075、cloud PR #1080(分歧专节)、ADR-0053 D-A1、sql-driver-filter-no-silent-drop.test.ts。

cloud 分片 PM session_015W6nhsDrz6zWQc8je12a1t 代立;labeling ≠ claiming,本会话不认领。


Generated by Claude Code

Activity

  1. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    Contributor

    分诊(PM 循环第 1 轮,会话 session_01Pbu27iNUfQCHeuS551Rqo7):挂 needs-user-decision 上交 —— A(spec 接纳数组方言)/ B(响亮弃用)二选一是公开契约形状定调,且无论取哪边都动 packages/spec(A 改 where 声明,B 需弃用记录),届时归 spec 车道执行。正文两轴分析已足,PM 补一条:B 之前的「清点调用方」是可派的前置侦察(不动契约,只出报告),维护者若先要清单可说一声,本车道即派。在定调前 cloud remote 的响亮拒收是安全侧,不需等待(正文已述)。


    Generated by Claude Code

  2. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    Contributor

    清点侦察完成(engine/services 车道 PM 派发,只读;会话 session_01Pbu27iNUfQCHeuS551Rqo7)

    对 origin/main @ 1f82d1e2c 全量清点,关键读数:

    类别 数量
    以数组形式真正到达 SqlDriver.applyFilters 的生产调用方 0
    写元组形式、但经 Door 1(parseFilterAST)转换的生产授权点 5 处(showcase 两文件)
    制造元组的已发布库 packages/client FilterBuilder,16 处
    教数组形式的已发布文档/契约 13 处(README×3、llms.txt、skills×4、spec TSDoc×4、query-adapter)
    content/docs/** 提及 0(且 data-api.mdx 明文教反对)
    钉住 Turso/RemoteTransport 分叉的测试 0

    两个决定性事实:(1) 数组只有两扇门 —— HTTP/协议门(protocol.ts:4533)一律转换或 400,唯一放行数组的是进程内 engine Door 2(engine.ts:4309 明文祝福「expression tree 归 driver 解释」并有 pin 测试);(2) FilterArray 是只有名字没有定义的类型 —— UI 授权面拿它当契约教,协议层从未声明它;同时 TursoDriver 是 SqlDriver 的下游子类,原样继承方言,而 cloud 的 RemoteTransport.buildWhereSQL 响亮拒收 —— 同一产品内部的行为分叉,两侧零测试。

    推荐更新:C > B > A(侦察发现的第三选项,PM 按三轴复核后改推):

    C. 单一下沉缝:FilterArray 在 spec 里正式声明为仅输入的授权糖(React props / FilterBuilder / wire $filter 面),engine 与协议门一样调用 parseFilterAST 下沉为 FilterCondition —— Door 2 关闭,驱动的数组分支结构性不可达,四个驱动的方言实现随后可无行为变化地删除。

    • 长远合理性:唯一让「驱动只说 FilterCondition 一种话」成立的路;A 要每个驱动/transport 永远维护两套编译器,B 要显式撕毁三份已发布契约(filter-no-silent-drop、reject-malformed-filter-array 的保留条款、engine-findone-contract 的 pin)且四驱动必须同步;C 只退役一条 pin,且是刻意的。
    • 实际业务需求:授权面人体工学零损失 —— showcase 五处、FilterBuilder 十六处、skill 契约全部原样工作;wire 零变化。
    • 防 AI 写错:FilterArray 终于有定义(今天它是纯陷阱:契约教你写、协议不认账);下沉单点 = 单一语义;Turso 分叉随驱动分支删除而消灭。

    附注:方言引入者的归因超出本 checkout 的浅克隆窗口(93 commits),需全深度 git log -S "nextJoin" 补;完整清点报告(含 8+5 个测试文件清单、逐调用方迁移难度表)存于本次侦察 transcript,需要可整理成 gist。执行上 C 动 packages/spec(声明 FilterArray)+ engine 下沉调用 + 驱动删除,跨 spec/engine —— 建议 spec 车道牵头声明、engine 车道(本会话)做下沉与删除,contract-first 排序。等维护者拍板。


    Generated by Claude Code

  3. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    Contributor

    维护者拍板:取 C(单一下沉缝)

    不取 A(spec 接纳数组方言,每个驱动/transport 永远维护两套编译器),不取 B(响亮弃用,要显式撕毁三份已发布契约且四驱动必须同步)。C:FilterArray 在 spec 里正式声明为仅输入的授权糖(React props / FilterBuilder / wire $filter 面),engine 与协议门一样调用 parseFilterAST 下沉为 FilterCondition,Door 2 关闭,驱动的数组分支结构性不可达后无行为变化地删除。needs-user-decision 摘除。

    依据即侦察清点的两个决定性事实:以数组形式真正到达 SqlDriver.applyFilters 的生产调用方为 0(所以下沉不损失任何现存行为),而 FilterArray 今天是有名无定义的纯陷阱(UI 授权面拿它当契约教、协议层从未声明它)。C 的授权面人体工学零损失、wire 零变化,同时消灭 TursoDriver-vs-RemoteTransport 的零测试分叉。

    执行顺序(contract-first,跨车道)

    1. spec 车道(先,阻塞项):在 spec 声明 FilterArray 为仅输入形状 —— 它今天被四份已发布契约教却从未被声明,这一步单独就有价值。这是本单唯一的阻塞前置,engine 半边在它落地前无法开工。
    2. engine 车道(本会话,后):engine Door 2(engine.ts:4309)改调 parseFilterAST 下沉;确认驱动数组分支不可达后删除四驱动的方言实现;退役 engine-findone-contract 里那条祝福数组直达驱动的 pin(刻意退役,PR 里写明)。

    本车道现在不认领、不挂 pm:dispatched —— 等 spec 半边落地后由本车道接第 2 步。在此之前 cloud remote 的响亮拒收是安全侧,维持不动。

    方言引入者的归因仍缺(浅克隆窗口不足,需全深度 git log -S "nextJoin"),非阻塞。


    Generated by Claude Code

  4. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    Contributor

    spec 半边已按移交协议立单:#5285(声明 FilterArray 为仅输入授权糖,拍板 C 第 1 步)。spec 车道(会话 session_01ErbEDVAg1No9gdg1pgDAGB)下一空槽即派;落地后 engine 车道可接第 2 步(Door 2 下沉 + 四驱动删除)。建议 engine 侧在本单补一行 Blocked-by: #5285 以便解锁扫描自动回队。


    Generated by Claude Code

  5. self-assigned this
    on Aug 4, 2026
  6. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    Contributor

    阻塞解除 → 认领 + 派发第 2 步(engine 车道 PM,会话 session_01Pbu27iNUfQCHeuS551Rqo7)

    前置已落地:#5285 的 spec 半边合入 origin/main = b49ccfdfe(PR #5306)。核实过实况,不是照抄 PR 标题 —— packages/spec/src/data/ 下 FilterArraySchema / FilterArray / FilterArrayOperator 均已导出,且 filter-array-declaration.test.ts 里已有 pin 钉死两件事:该形状被声明、且仅输入(where 接受 FilterArray 会让测试失败)。第 2 步的契约依赖到位。

    pm:blocked 摘除,转 pm:dispatched。分支 claude/issue-5158-lower-filter-array-at-engine-door,专用 worktree /home/user/objectstack-issue-5158,域 domain:engine。

    已定范围(拍板 C 第 2 步,不要重新论证 A/B):

    1. engine Door 2(engine.ts:4309 那处明文祝福「expression tree 归 driver 解释」)改调 parseFilterAST,把 FilterArray 下沉为 FilterCondition —— 与协议门(protocol.ts:4533 Door 1)同一条缝。
    2. 确认驱动的数组分支结构性不可达后,删除四驱动的方言实现。删除前要有证据(不是推断),PR 里给出。
    3. 退役 engine-findone-contract 里那条祝福数组直达驱动的 pin —— 刻意退役,PR 正文写明是拍板 C 的直接后果,不是顺手删测试。

    侦察已确立、不必重查的事实(来自本车道 15:23Z 的清点):以数组形式真正到达 SqlDriver.applyFilters 的生产调用方为 0;写元组形式但经 Door 1 转换的生产授权点 5 处(showcase 两文件);FilterBuilder 制造元组 16 处;教数组形式的已发布文档/契约 13 处 —— 这些授权面在 C 下全部原样工作,wire 零变化。TursoDriver 是 SqlDriver 下游子类,原样继承方言,删除后与 cloud 的 RemoteTransport.buildWhereSQL 拒收自然合流,那处零测试分叉随之消灭。

    同日 churn 警示:packages/plugins/driver-sql/src/sql-driver.ts 今天被改过三次(#5243 归约、#5296 NULL-safe $not、#5327 {field:{}} 拒收),packages/objectql/src/engine.ts 被改过两次(#5270 批量按行、#5283 单记录 delete 绑 previous)。必须基于最新 origin/main 开工并逐条重核 issue 与本评论引用的行号。

    ⛔ 不碰 packages/spec/** —— 第 1 步已由 spec 车道落地,本单只消费。
    ⛔ 不碰 content/docs/releases/**。


    Generated by Claude Code

  7. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    Contributor

    开工认领(engine 车道 dev,第 2 步)

    会话 session_01Pbu27iNUfQCHeuS551Rqo7 派发的 engine 半边由本 dev 会话接手。

    • 分支:claude/issue-5158-lower-filter-array-at-engine-door
    • worktree:/home/user/objectstack-issue-5158,基于 origin/main = 0f1711470(已含第 1 步的 b49ccfdfe / PR feat(spec): 声明 FilterArray 为仅输入的授权糖(#5158 拍板 C 第 1 步) #5306)
    • 范围:Door 2 下沉 parseFilterAST + 四驱动数组方言删除(需先证不可达)+ 刻意退役 engine-findone-contract 那条 pin
    • ⛔ 不动 packages/spec/**、不动 content/docs/releases/**、不碰 cloud 仓

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions