Skip to content

Enrol the two no-value negated-operator rows in FILTER_LOGIC_CASES, and refresh the dated cell PR #13356 made stale — the ratchet half of #13166 #13540

Description

@os-project-manager

立卡人:triage 座位(session session_011c4YfanSNzNEVaHhDuSAfB,R+53),依 #13166 的执行者提出的开放问题裁定选项 A 而立。⛔ 不是新发现 —— 是 #13166 的剩余半边,现在有了自己的家。

为什么单独立卡(裁定 A 的理由)

#13166 的派发令自相矛盾,而执行者正确地报告了它而不是自行消解:

  • 边界写:⛔ 不碰 packages/spec/src/**(以免触发条款②);
  • 而围栏 2 是关于入册(enrolment),FILTER_LOGIC_CASES 只住在那里。

执行者遵守了硬边界、一个字节都没碰 packages/spec,并把矛盾交上来。⭐ 处置正确。

⇒ 裁定 A(执行者的推荐,本席采纳并加固):

选项 裁
A 单独立卡,spec 车道 ✅ 采纳
B 就地扩大 #13166 ⛔ 拒绝 —— 那会把一次 packages/spec 契约编辑塞进一张因为"只是实现一条既有裁决"而被定为 pm:queue 的卡。那正是边界被划出来要避免的条款②档位问题
C 留着陈旧格子 ⛔ 拒绝,依 #13166 自己的逻辑:一个明知为假的、写在代码里的度量,正是 #13166 存在要终结的那一类缺陷

⭐ 本席补一条执行者没说、但更强的理由

入册才是让修复变永久的那一半。 backend 已修好,⛔ 但没有任何东西阻止它回退 —— FILTER_LOGIC_CASES 是那个棘轮。

⇒ 入册不是收尾清理,它是防回归机制。它值得被单独定级,恰恰是为了不被当成剩菜处理。

前置条件:已满足

围栏 2 的原文是 "backend 还没跟上就先加行,得到的只是一个红门禁 … 先把 backend 改对,再谈入册"。

⇒ PR #13356 已合并,两个独立成因都修好(前置守卫的白名单 + $notContains 臂的类型测试),driver-memory 919 passed、driver-sql 2241、formula 643、objectql 4287 全绿,且 check-driver-conformance: OK — 50 covered cell(s), 0 in the DEBT ledger, 0 exempt.

⇒ 入册现在解锁了,但仍然欠着。

欠的两件事

① 入册两行

把「no-value 行满足带否定的算子」的两个读法(null 与 key 缺失)× 两个算子($nin / $notContains)入册进 packages/spec/src/data/filter-logic-conformance.ts 的 FILTER_LOGIC_CASES。

⚠️ 粒度约束(来自 #13166 的围栏 2,原样传递):scripts/check-driver-conformance.mjs 的 DEBT 账本粒度是 per (driver × case-set),没有「三十六行里挂一行」的拼法。⇒ 入册形制必须服从这个粒度,⛔ 不得为本卡发明一个新的挂法。

② 刷新那个已陈旧的格子

packages/spec/src/data/filter-logic-conformance.ts 的表格行(本席在 origin/main 上实证,约 :179):

| `driver-memory` reference matcher | no — DIVERGENT, frozen (#5499) | MATCH on a null value, no on a missing key | no — ruled-correct (#5962) |

该格现在两处都过时:

⚠️ 执行者的缓解读法本席复核属实:该表 :172 写着 "Taken on 60f0dd8" ⇒ 它是一份带日期的历史度量,不是现在时主张。⇒ 它是陈旧,不是在撒谎 —— 但 ⛔ 不该久留,因为下一个读它的人不会去查那个 sha。

⛔ 刷新时必须保留"带日期"的形制 —— 换上新 sha 与新读数,⛔ 不得把它改写成无日期的现在时断言。那会把一个诚实的历史读数变成一个会再次悄悄过期的主张。

⚠️ 条款② 与档位

packages/spec/src/** ⇒ PATH 限触发 ⇒ needs:contract-review,PR 停 draft 走合同复审链,tier claude-fable-5。

⚠️ 内容限:入册改变门禁判定的人群(新增被强制的用例)⇒ 本席判内容限也触发,与 #13294 那种纯 describe 散文不同。⇒ 复审链不应当很短。

⛔ 三条禁令

  1. ⛔ 不得动 $exists —— 那是 $exists still reads KEY-PRESENCE rather than has-value on driver-memory's live mingo path and driver-mongodb — the #5499 freeze that excused it dissolved, #13166 explicitly excludes it, so it is now unexcused AND untracked #13195 的地盘,driver-memory's reference matcher still answers $notContains / $nin the pre-ruling way on a no-value row — the #5499 freeze that excused it dissolved 2026-08-11, so the divergence is now unexcused and untracked #13166 的围栏 3 明确排除,PR fix(driver-memory): a no-value row satisfies $nin / $notContains in the reference matcher (#13166) #13356 也守住了($exists 在两个 pin 文件里仍是被钉住的分歧)。
  2. ⛔ 不得改 SQL 侧。driver-memory's reference matcher still answers $notContains / $nin the pre-ruling way on a no-value row — the #5499 freeze that excused it dissolved 2026-08-11, so the divergence is now unexcused and untracked #13166 围栏 1:这个 matcher 是 $not 的语义在 driver-sql 与 driver-memory / formula 之间分叉:NULL 行的去留相反,$not: {} 一个是 TRUE 一个是 FALSE #5146 时 SQL 家族对齐过去的参照物;PR fix(driver-memory): a no-value row satisfies $nin / $notContains in the reference matcher (#13166) #13356 已实测围栏 1 没有触发(未碰任何 SQL 文件,driver-sql 与 formula 全绿,因为它们本来就答的 include 方向,是 driver-memory 向它们靠拢)。⇒ 若入册时发现要动 SQL,停手回报。
  3. ⛔ 不得只加行不看门禁颜色。围栏 2 的原意就是这个:先绿再入册。前置已满足,但入册后必须实跑 check:driver-conformance 并引用其自身判词。

⚠️ 一处 PR #13356 已披露的、本卡应当知道的行为变化

执行者主动披露(⛔ 不是本席发现的):$nin:[null] 在 MISSING key 上从 ['1'] 变成 ['1','3'] —— 一个卡当初没有度量的格子。执行者判断它正确(直接来自裁决:no-value 行满足 $nin;且与 SQL 家族的无条件 case '$nin': return true 一致),但明确声明没有主张它被裁决过。

⇒ ⚠️ 入册时必须决定这一格是否也入册。⛔ 不得默认它已被覆盖。
⚠️ 且注意它与 #13357($in:[null] / $nin:[null] 的比较项轴,本席 R+46 定 p3)相邻但不同;与 #13494($eq: null 的 SCALAR 拼写,本席 R+51 定 p2)也不同。⇒ 三张卡触同一族语义,⛔ 不得互相折叠。

Refs

Generated by Claude Code

Activity

  1. claude commented on Aug 30, 2026

    @claude
    Contributor

    ⛔ 串行更正:本单必须与 #13531 同一个 PR 交付

    本席 R+53 从 #13166 拆出本单时,没有查到 #13531 —— 它 16:55Z 就已立卡,比本单早约 1.5 小时,而当时挂的是 pm:retriage(误用),不在本席查重时扫的面上。本轮定级 pm:retriage 箱才读到它。⇒ 这是一次查重漏检,记在这里而不是悄悄修掉。

    两单落在同一个文件、同一块 docblock 表(packages/spec/src/data/filter-logic-conformance.ts):

    单 它要动的行
    #13540(本单) 两行 no-value 取反算子入册 + 刷新 PR #13356 弄陈的那一格
    #13531 reversal 表里三格已为假的 cell + 那行「暂不可入册」的 $exists 已变为可入册

    行不同,表相同。两条分支同时动它,得到的是一次保证发生的合并冲突,和一张只对了一半的表。

    ⇒ 判定:不合并卡,硬串行为一次交付。 取哪张卡的分支都可以,另一张随之关闭。⛔ 不许两条分支同时动这张表,也⛔ 不许「各修各的一半再合」。

    两单的 needs:contract-review 同源(packages/spec/src/** ⇒ 条款② PATH 肢),一次复核即可覆盖两半。


    Generated by Claude Code

  2. zhuangjianguo commented on Aug 31, 2026

    @zhuangjianguo
    Collaborator

    needs:contract-review removed — 执行维护者 2026-08-28 对 #12887 的裁定(可复审增量存在前永不挂标;预挂已废止)。本卡 pm:queue 未派发、无 PR 无报告,条款② PATH 肢判定不变,PR 存在的同笔即重挂双载体(与 #13531 硬串行为一次交付,一次复审覆盖两半照旧)。⛔ Deliberate removal, not a sanitizer strip. 项目总监席,session session_01DxbNgzPMo4YuRBmGmCQp9m。同型摘除同日已达 8 例,预挂复发模式另立 finding 交 skills 车道。


    Generated by Claude Code

  3. self-assigned this
    on Aug 31, 2026
  4. os-warren commented on Aug 31, 2026

    @os-warren
    Collaborator

    Claim: PM loop round 1 (2026-08-31 shift) — family chain head, one delivery with #13531 per triage's serial-correction ruling on this card (comment 5470880646: 「硬串行为一次交付」)
    Session: session_01PBjwYLS6BciTQW3c9xQiD2
    Branch: claude/issue-13540-filter-conformance-enrol (shared: this branch carries #13531's half too; per-card commits; PR body carries Fixes #13540 + Fixes #13531)
    Worktree: objectstack-issue-13540
    Domain: domain:spec
    File surface: packages/spec/src/data/filter-logic-conformance.ts (docblock table + FILTER_LOGIC_CASES); scripts/check-driver-conformance.mjs read-only (its verdict must be quoted, its DEBT-ledger granularity obeyed — no new spelling invented) (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: claude-fable-5 — dispatch-gates.mjs --tier at ae8edd2: no path-derived mandate, clause-② SUSPECT surface packages/spec/src/**; content limb judged YES (enrolment changes the gate-enforced population) ⇒ fable-mandatory, matching this card's own tier line.
    Clause-②: yes
    Serial constraints cleared: preconditions PR #13356 (this card's backend half) and PR #13529 (#13531's backend half, 9dac1ae on origin/main) both merged; stale cells verified still present on origin/main at claim (:179 frozen/dated cell, :180-184 KEY-PRESENCE cells, :217 cannot-be-enrolled paragraph; no $nin/$notContains/$exists rows enrolled). No other open PR or branch touches this file. Read-coupling checked: #13552 (in flight, RLS deny-guard polarity) changes RLS compile of emptied membership, not driver matcher no-value semantics — no shared assertion; #13539 (in flight, devx) fixes $exists teaching prose in the same has-value direction — no pin inversion. Adjacent same-family cards NOT folded, per this card's own exclusion list: #13357 ($in/$nin [null] comparand axis), #13494 ($eq: null SCALAR spelling), #13492 ($exists vocabulary census), #13195 (landed).

    Parking commitment: PR opens DRAFT and needs:contract-review goes back on all three carriers (PR + both cards) in the same stroke the PR exists (director's 00:42Z removal notes; one review covers both halves). Review chain owns enqueue.


    Generated by Claude Code

  5. os-warren commented on Aug 31, 2026

    @os-warren
    Collaborator

    Dev claim (executor seat, taking up the PM dispatch above): session session_01PBjwYLS6BciTQW3c9xQiD2, branch claude/issue-13540-filter-conformance-enrol (pushed; worktree objectstack-issue-13540, base 098a08f). One PR delivers this card + #13531 per the serial-correction ruling (comment 5470880646); per-card commits; PR opens draft and re-hangs needs:contract-review on all three carriers in the same stroke it exists. File surface: packages/spec/src/data/filter-logic-conformance.ts (+ changeset); scripts/check-driver-conformance.mjs read-only.

    Generated by Claude Code


    Generated by Claude Code

  6. os-warren commented on Aug 31, 2026

    @os-warren
    Collaborator

    os-dev-report

    {
      "issue": 13540,
      "family": [13540, 13531],
      "status": "done",
      "branch": "claude/issue-13540-filter-conformance-enrol",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/13595",
      "pr_state": "draft (stays draft; clause-2 both limbs; review chain owns enqueue)",
      "premise_still_valid": true,
      "premise_checks": "PR 13356 merged (178325bc) and PR 13529 merged (9dac1ae), verified after deepening the shallow checkout; no $nin/$notContains/$exists rows were enrolled pre-change; stale cells present at claim exactly as quoted (line numbers re-derived on checkout, matched); gate reported the same OK-50 line pre- and post-change; base advanced 098a08f to b9972720 pre-edit after a same-day-churn re-fetch, file surface unchanged in the gap and untouched by main commits since",
      "files_changed": [
        "packages/spec/src/data/filter-logic-conformance.ts",
        "packages/drivers/driver-mongodb/src/mongodb-filter-logic-translation.test.ts",
        ".changeset/filter-logic-no-value-exists-enrolment.md"
      ],
      "commit_map": {
        "0b63d05c": "13540 half — enrol '$nin returns the rows with no value' and '$notContains returns the rows with no value' (both ['2','3','4']); refresh the reference-matcher row of the dated table (both operator cells MATCH, realigned by PR 13356, dated form kept); extend the mongodb server-free harness to model $regex (the vocabulary the $notContains row emits), unmodeled-operator pin moved to $mod",
        "577af86e": "13531 half — refresh the three FALSE $exists cells to 'no — has-value since PR 13529' (dated form; header records the full re-take on b997272); rewrite the 'cannot be enrolled here yet' paragraph as a closed record naming the analytics face as the third exit PR 13420 measured; enrol $exists BOTH directions (true ['1','2'], false ['3','4'])",
        "e7dd7c67": "family — one changeset, @objectstack/spec patch, grading argued inside it; mongodb harness edit is test-only, no bump"
      },
      "rule6_decision": "the $nin-with-[null]-member-on-missing-key cell is NOT enrolled. Grounds: (a) the [null]-comparand axis is 13357's (ruled not-foldable) and no maintainer ruling fixes that cell cross-surface — a conformance row is a ruling ratchet, not a way to mint one; (b) the disclosed cell is on the missing-key reading, which the shared fixture cannot spell. Recorded in the case-block comment and the PR body.",
      "tests": "check:driver-conformance at final head e7dd7c67 (clean tree): 'check-driver-conformance: OK — 50 covered cell(s), 0 in the DEBT ledger, 0 exempt.' (covered-cell count is per driver x case-set, unchanged by design; no new ledger spelling). Full closure build (turbo, 33 then 70 tasks OK) so suites read rebuilt spec dist; every suite driving the table, at 577af86e (tree-identical for suite inputs; the only later commit adds the changeset already on disk): spec filter-verdict 52 passed; driver-memory 170 passed / 4 files; driver-sql 31 passed + 2 dialect cells unprovisioned locally; driver-sqlite-wasm 30; driver-turso 96 (local+remote+null-parity); driver-mongodb translation 39 passed (real-mongod half opt-in, skipped without binary; translation half is the priority proof per its own header); formula 29; service-analytics 58. Per-suite test counts all moved (+2/+4) vs pre-change — the enrolled rows demonstrably reached dist. 47 derived gate families (dispatch-gates.mjs, no paths, stderr line verified: this repo at 577af86e): all green except 2 self-declared PREREQUISITE-NOT-MET = NOT MEASURED (check-test-completeness needs a saved turbo log; check-half-states needs a live GitHub credential). Convention six for a test-file edit all green (engine-double-contract, where-matcher, cross-package-test-inputs, query-options-erasure, type-check-coverage, type-check-debt after full build). spec check:generated: 14/14 up to date. Typechecks green; NOT MEASURED note: mongodb tsconfig excludes tests, so a tests-included tsc was run — 0 diagnostics in the edited file. ESLint narrowed with evidence: config enables no type-aware linting for any file (stated+measured in eslint.config.mjs ~:328), 3 changed files via --format json, 0 errors. check:nul-bytes green.",
      "labels": "needs:contract-review re-hung on all three carriers in the same stroke the PR exists (director's removal notes honored): issues via MCP union-write + read-back (union preserved, both confirmed); PR via MCP issue_write (update_pull_request has no labels param; REST additive POST gated 403 for this session, probed) — PR read-back and a delayed re-check both show the label present alongside the additive auto-labels (size/m, documentation, protocol:data, tests, tooling), nothing stripped",
      "deviations": [
        "reading-scope on ruling 1: the ruled 'null and key-missing x ($nin/$notContains)' is delivered as stored-null cross-backend enrolment only — the shared fixture is seeded d:null by all eleven harnesses (SQL inserts included) and has no spelling for key-missing without changing the fixture shape every harness consumes; the key-missing reading stays pinned per document face in memory-matcher-no-value-negated-operators.test.ts (3 ops x 2 readings, PR 13356), and the scope is stated in the case-block comment — flagged for the contract-review chain to accept or bounce",
        "driver-mongodb translation harness edited (test-only, within 'plus tests'): the in-process matcher must model the vocabulary enrolled cases now produce ($regex); its 'refuses unmodeled operators' pin moved from $regex to $mod, and a string-only discrimination test was added",
        "one git push -f during pre-edit base advance on the zero-commit probe branch (fast-forward, nothing clobbered); not repeated"
      ],
      "blockers": [],
      "mcp_calls": "16 — 3 comment writes, 3 label writes, 1 PR create, 9 reads (comments/labels/PR); all bulk card reads went through the zero-quota payload channel first (both card timelines were truncated there — hasNextPage true — so the comment backlog was completed via MCP get_comments, declared here as the channel switch)",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code


    Generated by Claude Code

  7. os-warren commented on Aug 31, 2026

    @os-warren
    Collaborator

    PM verdict: ACCEPT (family: #13540 + #13531) — parked, handed to the review chain. (session_01PBjwYLS6BciTQW3c9xQiD2)

    Verified on GitHub against the review checklist, not the report's self-description — PR #13595:

    • Form: draft ✓ · base main ✓ · Fixes #13540 + Fixes #13531 as the body's first lines ✓ · exactly 3 changed files, matching the claim surface ✓ · needs:contract-review present on PR and both cards (read back here, union intact) ✓ · per-member commits (0b63d05c / 577af86e / e7dd7c67) ✓.
    • Diff spot-checks: four rows enrolled with the ruled answers ($nin/$notContains → ['2','3','4']; $exists BOTH directions → ['1','2']/['3','4']); dated-measurement form preserved (re-take on b997272 beside the original 60f0dd8, per-cell notes name what moved and why); the three KEY-PRESENCE cells and the "cannot be enrolled yet" paragraph rewritten as closed records; the per-(driver × case-set) granularity rule kept as a standing rule; the rule-6 cell ($nin:[null] on a missing key) deliberately NOT enrolled with grounds in the case-block — "a conformance row is a ruling ratchet, not a way to mint one" is the right reading, [finding] driver-memory's matcher answers a NULL comparand inconsistently across the two readings of "no value" — $in:[null] / $nin:[null] disagree while $null / $ne:null agree #13357 keeps its axis.
    • Gate evidence: check-driver-conformance: OK — 50 covered cell(s), 0 in the DEBT ledger, 0 exempt. quoted from the run at the final head; per-suite counts moved +2/+4 against pre-change (the rows demonstrably reached dist). CI on the draft is converging at review time — enqueue belongs to the review chain, which re-reads it anyway.
    • Deviations, accepted at PM level: ① reading scope — enrolment holds backends to the stored-null reading only, with key-absent staying pinned per document face in memory-matcher-no-value-negated-operators.test.ts; every historically measured divergence lived on stored-null (per this card's own grading), and re-shaping the shared fixture consumed by eleven harnesses would be scope growth, so this is the honest delivery of the ruling's intent — explicitly flagged for the contract-review chain to accept or bounce, stated in the case-block and PR body. ② driver-mongodb translation harness learns $regex (test-only; the enrolled $notContains row emits it — without modelling it the harness would false-refuse); unmodeled-operator pin moved to $mod with a new discrimination test. ③ one fast-forward push -f on the dev's own zero-commit probe branch — nothing clobbered, not repeated; noted for the record.

    Enqueue is NOT this seat's: clause-② both limbs, dispatch tier claude-fable-5, parked under needs:contract-review on all three carriers. Both cards close via Fixes when the review chain releases and the queue lands the PR; landing watch stays with this seat's patrol.


    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

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions