refactor(spec,plugin-security)!: QueryAST 不再声明没有执行器运行的成员 — joins/windowFunctions 墓碑化,liveness ledger 接管请求面 (#4286) - #4294
Merged
Conversation
…cutor runs (#4286) Tombstone `query.joins` and `query.windowFunctions` (retiredKey — authoring either is a tsc error and the parse carries the prescription), and delete the orphaned Join and WindowFunction schema clusters with their keys: `expand` is the live spelling for related records, and the one live window-function door (`SqlDriver.findWithWindowFunctions()`) consumes its own flat driver shape that the spec vocabulary never matched. Both removals register as protocol-18 semantic migrations (`query-joins-retired`, `query-window-functions-retired`) — QueryAST is a request shape with no stored source to rewrite (#4196 precedent). Both names stay reserved at the REST boundary while the tombstones live (retiredKey keeps them in `keyof QueryAST`). Mark the six search sub-flags and `AggregationNode.filter` `[EXPERIMENTAL — not enforced]` — declared engine affordances the ADR-0061 expansion and the aggregation paths never receive. Close the gate that let the class stay invisible: `QuerySchema` joins the liveness ledger through SPEC_ONLY_SCHEMAS as governed type `query` (liveness/query.json — 15 live with evidence, 7 experimental via describe markers, 5 dead). `cursor` / `distinct` / `having` are recorded dead with evidence pending their #4286 step-3/4 dispositions, not unilaterally removed — `distinct` is mis-wired (its only effect is REST count-suppression) and `having` is the strongest enforce candidate (engine.aggregate() currently rebuilds the driver AST without it). The FLS predicate guard drops its windowFunctions walk (the clause no longer exists to leak through); the `having` and `aggregations[].filter` walks stay while those members stay declared. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012K2BX3WQwPBA2ZBehqJUBX
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 3 package(s): 110 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-zhuang
marked this pull request as ready for review
July 31, 2026 04:22
This was referenced Jul 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
落实 #4286 的第 1、2、5 步(机械层 + 闸门)。第 3 步(
having)与第 4 步(cursor/distinct)按 issue 自己的定性留给维护者裁决,本 PR 只在新 ledger 里把三者记为dead并写明证据与待决事项——所以不关闭 #4286。处置一:
joins/windowFunctions移除(墓碑化)retiredKey()墓碑(BaseQuerySchema非 strict,裸删除会被 zod 静默剥离——ADR-0104 那一类):作者侧tsc直接报错,运行时 parse 给出带 FROM→TO 的处方,连joins: []也拒绝。JoinNode/JoinNodeInput/JoinNodeSchema/JoinType/JoinStrategy与WindowFunction/WindowSpec/WindowFunctionNode(api-surface 少 10 个导出;data/JoinNode等 6 个 JSON schema 出清单)。SqlDriver.findWithWindowFunctions()吃的是驱动自己的扁平形状({ function, alias, partitionBy?, orderBy? },见 driver 测试与buildWindowFunction)——spec 节点声明的field/over/frame那个门从未读过。保留 spec 词汇表只会一层之隔地重演「声明 ≠ 执行」,所以随键删除;文档里驱动门示例已改为真实形状。query-joins-retired/query-window-functions-retired)——QueryAST是请求面、从不落盘,链无源可改写,循 [P3] data:FieldNode's nested-select object form is declared but nothing produces or consumes it — enforce or remove #4196(query-field-node-object-form-retired)先例;gen:schema闸门 (b) 据此放行。RESERVED_LIST_QUERY_PARAMS(retiredKey保留keyof QueryAST成员),行为零变化;去保留发生在墓碑到期删除时,已写进QUERY_AST_KEYS注释提醒后人。windowFunctions遍历(条款已不存在,无可泄漏);having与aggregations[].filter的遍历保留——它们仍在声明面上,guard 就绪正是日后 enforce 的安全前提。处置二:六个 search 旗标 +
AggregationNode.filter标记 experimentalsearch.{fuzzy,operator,boost,minScore,language,highlight}(ADR-0061 展开只读query+fields)与aggregations[].filter(SQL/内存两路都不应用)加[EXPERIMENTAL — not enforced]describe 标记。无 wire/兼容影响;ledger 直接从标记解析状态。处置三(第 5 步,核心):liveness ledger 接管请求面
QuerySchema经SPEC_ONLY_SCHEMAS进入 governed 类型query(webhook先例,但这是常驻覆盖——请求面没有 registry 可回折)。issue 点名的缺口正在此:ledger 只管作者写进元数据的东西,没人管调用者写进 query 的东西。liveness/query.json:27 个成员全分类——15 live(逐条 file:line 证据)/ 7 experimental(describe 标记)/ 5 dead。cursor(Tier A,QueryBuilder.cursor()在产、无驱动实现)、distinct(mis-wired 而非单纯 dead:唯一效果是 protocol.ts:3816 的 count 抑制,ADR-0078 从严)、having(engine.aggregate()重建 AST 时根本不带它——最强的 enforce 候选)各自带verifiedAt与待决注记。验证
tsc --noEmit干净。packages/spec14 个闸门全 PASS(check:liveness报query 27 classified (live 15, experimental 7, dead 5));check:generated全部最新——api-surface/docs 按其裁定窄向重生成,strictness ledger 行随四个z.object站点的删除更新(9→5)。joins: []亦拒、undefined放行、替代写法(expand/点路径)可解析。query-syntax.mdx/data-modeling/queries.mdx的 joins/window 小节改为移除记录,objectstack-queryskill(SKILL.md + rules/aggregation.md + evals)不再教「schema-reserved」;三处导航卡片文案不再宣传 joins(Prime Directive chore: version packages #10 的「declared ≠ enforced 不得广告」)。@objectstack/specmajor(FROM→TO 映射与一行修复齐备)+@objectstack/plugin-securitypatch。升级指南/spec-changes 待 PROTOCOL_MAJOR 翻到 18 时由生成器自动收录(与 [P3] data:FieldNode's nested-select object form is declared but nothing produces or consumes it — enforce or remove #4196 同轨)。🤖 Generated with Claude Code
https://claude.ai/code/session_012K2BX3WQwPBA2ZBehqJUBX
Generated by Claude Code