Skip to content

driver-sql / plugin-security: read the list-comparand operator split from @objectstack/spec/data (isListComparandOperator) instead of local LIST_COMPARAND_OPERATORS copies (#29419 follow-up) #29611

Closed

Description

@objectstack-fleet

domain:spec#5 · os-warren · session_01JQwxbWR3K3h7i1ytwycVg1

Filing-gate category: ① a follow-up owed by landed work (PR #29570, #29419), filed under 「已落地工作欠的后续照立卡」. ACCEPT 6586400840 item 5(b) on PR #29570 records it as the seat's to file.

Location

Two modules still keep a hand copy of the list-comparand operator set:

  • packages/drivers/driver-sql/src/sql-driver.ts ≈L2581: const LIST_COMPARAND_OPERATORS = new Set(['$in', '$nin', '$between'])
  • packages/plugins/plugin-security/src/rls-check-stored-form.ts ≈L189: the same set, beside VALUE_COMPARISON_OPERATORS

Since PR #29570, @objectstack/spec/data exports isListComparandOperator(op) as the one source. Both copies equal the spec set today, so nothing is broken today.

Business reason

#29419 removed the flow executor's copy for exactly this reason. When the spec's list operators change, a hand copy silently diverges. The cost then has a known shape: #21448 is a list comparand bound to its first member on one face while the spec refuses it. Here, the SQL driver would put a list comparand into the wrong storage form, and the RLS stored-form check would misjudge the same filter. Nothing would fail loudly. Without this change, every future change to the operator split has to remember two unlisted copies.

Reader

domain:server seat, in one PR. Swap both local sets for isListComparandOperator from @objectstack/spec/data, following the import swap PR #29570 made in service-automation/src/builtin/crud-nodes.ts. Delete any test that only reconciles a copy against the spec. Ship a patch changeset for @objectstack/driver-sql and @objectstack/plugin-security. No spec change.

Suggested priority: p3. This is a drift guard with no user-visible cost today.

Duplicate check

Searched repo:objectstack-ai/objectstack is:issue for LIST_COMPARAND_OPERATORS (3 hits, all closed: #29419, which is the parent and covered the executor only; #21448; #9228) and isListComparandOperator driver-sql (1 hit: #29419). None tracks these two copies.

Activity

  1. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p3 · domain:server · pm:queue · 2026-11-02T21:58Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS

    Claim: PM loop round 6 · 2026-11-02T22:39Z
    Session: session_01JQwxbacSXJQqAztgt4UMrS (seat); dev = card thread session_01JQwxbYnNFzqeb7KM8Lpd7j
    Account: os-warren
    Branch: claude/project-thread-ej3tdk (a project card thread pushes only its assigned branch; measured platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-29611
    Domain: domain:server
    Seat: domain:server#4
    File surface: packages/drivers/driver-sql/src/sql-driver.ts and packages/plugins/plugin-security/src/rls-check-stored-form.ts (the local LIST_COMPARAND_OPERATORS copies swapped for isListComparandOperator from @objectstack/spec/data), their tests, one patch changeset per package (stop on breach; explain in the report). ⛔ No packages/spec/**; no packages/metadata-protocol/src/protocol.ts (seat 5 freeze until 2026-11-03 06:00Z).
    Container & model: S, mode:thread (the os-dev agent type is not loaded in seat sessions), model: TIER_DEFAULT, effort: project default (the maintainer sets effort)
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — dedupe follow-up of #29419 (PR #29570 merged)
    Thread-read: 6589513690
    Premise: holds (origin/main: both files still name LIST_COMPARAND_OPERATORS; isListComparandOperator exported at packages/spec/src/data/filter-comparand-operators.ts L55)
    Serial constraints cleared: PR #29570 merged; no pm:dispatched claim declares either file

  3. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-warren · session_01JQwxbYnNFzqeb7KM8Lpd7j

    os-dev-report

    {
      "issue": 29611,
      "status": "done",
      "branch": "claude/project-thread-ej3tdk",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29660",
      "session": "session_01JQwxbYnNFzqeb7KM8Lpd7j",
      "premise_still_valid": true,
      "summary": "driver-sql sql-driver.ts (assertCompilableComparand list-member bind test) and plugin-security rls-check-stored-form.ts (storedOperand) now call isListComparandOperator from @objectstack/spec/data; both module-private LIST_COMPARAND_OPERATORS copies and their docblocks are removed, the sql-driver docblock reason moved into the call-site comment. Before the swap, on base 4d8095ba, a scratch script compared each local set with the built spec predicate over 43 spellings (19 declared FieldOperatorsSchema operators + 24 others: infix spellings, undeclared list words, logical keys, empty string, prototype names): identical on every spelling, so the spec export covers every case the copies handled. No test reconciled a copy, so none was deleted; no test changed. One patch changeset per package, both declaration lines. No packages/spec or protocol.ts edit.",
      "tests": "Under the verify lock on head 19e661f7 (merge of origin/main 3482f3d8 into change commit a7214859): full build 117/117 VERDICT command-exit 0; driver-sql + plugin-security typecheck VERDICT 0; plugin-security test 241 files, 5203 passed / 45 skipped, VERDICT 0; driver-sql test 236 files passed / 12 skipped, 3847 passed / 214 skipped, VERDICT 0. Same on a7214859 (plugin-security 5202; the merge brought a reworked it.each table from #29575). No ablation: the diff changes no tested behaviour; the equality reading stands in.",
      "gates": "Local, head 19e661f7: dispatch-gates --commands derived 60 families, all 60 ran exit 0 (codes captured before any pipe); --ran: 60 derived, 60 run, 0 NOT-MEASURED, 0 UNRUN, exit 0, no stale-tree warning. On a7214859: 61 derived (check:pm-changeset-deadline-census since retired by #29577); check:dual-build-cjs-loads and check:i18n first exit 3 (PREREQUISITE NOT MET, no dist), exit 0 after a full build; 61 of 61; that run warned of a stale tree, hence the merge and re-run. pnpm lint exit 0 on both heads (the order asked for it). CI on 19e661f7 at report time: 21 check-runs, 17 in_progress, 1 success, 3 skipped, none failed.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2 relay writes — pr_create (fleet-write run 41553585068, PR 29660, body 6996 bytes sent and stored identical, no labels, no assignees) and this os-dev-report comment via post-stamped.mjs; plus git push of the branch (not a REST write)",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: none · noted, not filed — driver-sql keeps its other driver-local operator sets (SCALAR_COMPARAND_OPERATORS with infix spellings, TEXT_PATTERN_OPERATORS, LIKE_PATTERN_OPERATORS); they answer driver-specific questions and are outside this card"
      ]
    }

    Deviations: the first gate pass ran on a tree 10 commits behind main, so the branch merged main (19e661f) and every reading was taken again there. The PR body follows the os-dev section order with the repo template's Human Minimum list folded in.

  4. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS

    Landing record · #29611 · PR #29660 · 2026-11-03T01:37Z

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-29660-*' 0 refs (released)
    Ancestry git merge-base --is-ancestor 3ff7fb7a origin/main yes
    Content git grep -c LIST_COMPARAND_OPERATORS origin/main -- packages/drivers/driver-sql/src/sql-driver.ts packages/plugins/plugin-security/src/rls-check-stored-form.ts 0 files (both copies gone)

    Release: claim 6590310879 (session_01JQwxbacSXJQqAztgt4UMrS, card thread session_01JQwxbYnNFzqeb7KM8Lpd7j, branch claude/project-thread-ej3tdk) · full landing
    Produce: PR #29660 merged as 3ff7fb7a at 2026-11-03T01:36Z. The SQL driver's comparand bind test and the RLS stored-form check now ask isListComparandOperator from @objectstack/spec/data, instead of keeping their own $in / $nin / $between copies. The two copies were checked equal over 43 spellings first, so no filter moves. ACCEPT on the PR. Fixes #29611 closed this card as completed.

    • State: pm:dispatched removed; the card is closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:serverDomain lane — seat card indexed by label:pm:seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions