Skip to content

fix(eql): align JSON array flag with SQL and handle empty arrays - #1545

Draft
cipherstash-agent wants to merge 4 commits into
mainfrom
claude/project-thread-62v10t
Draft

cipherstash-agent wants to merge 4 commits into
mainfrom
claude/project-thread-62v10t

Conversation

@cipherstash-agent

Copy link
Copy Markdown
Contributor

Requested by CipherStash · project thread

Summary

Fixes CIP-5156 (E5, E6): the EQL v3 JSON array flag a disagreed between the Rust/TypeScript bindings and the SQL, and empty encrypted arrays broke the SQL accessors.

Changes

  • SteVecDocument now has an optional root a field. The SQL root validator allows it and the array accessors require it, so array documents the database accepts now parse in the bindings.
  • a (root and entry) is optional but non-nullable: schema "type": "boolean", TS a?: boolean, and a null is rejected on deserialize. This matches the SQL CHECK jsonb_typeof(...) = 'boolean'.
  • eql_v3.ste_vec returns an empty array instead of NULL for an empty sv. jsonb_array_length now returns 0 (was NULL), and jsonb_array_elements / jsonb_document_contains(jsonb[], jsonb) no longer raise "upper bound of FOR loop cannot be null". Their loops now use cardinality().
  • Regenerated bindings, JSON Schemas and @cipherstash/eql generated sources. Added a changeset.

Verification

  • cargo test -p eql-bindings: all pass, including new tests for root a round-trip and null rejection.
  • Built the SQL installer and ran the accessors against Postgres 16: empty array gives length 0, 0 elements, containment false; non-empty arrays unchanged.
  • New SQLx test v3_jsonb_empty_array_accessors passes against a local Postgres with the installer applied. The rest of v3_jsonb_tests.rs needs generated fixtures (CipherStash credentials), so I could not run it locally.

Related

  • Linear CIP-5156. Related: CIP-3876 (counted-container design, which may later drop a).

Review notes

  • The vendored TS types in languages/typescript/packages/protect-ffi/src/eql-v3-types are synced from the locked, published eql-bindings crate by design, so they are not touched here and pick up the change on the next release.
  • Only the entry and root a were made non-nullable. Other nullable-looking optional fields (i, v, h on entries) are out of scope.
  • No skills changes: skills/ does not mention the a flag shape.

Generated by Claude Code

SteVecDocument now models the root `a` flag the SQL validator allows and the
array accessors require. Entry/root `a` is optional but non-nullable in the
bindings, schema and TypeScript, matching the SQL CHECK. ste_vec() returns an
empty array instead of NULL for an empty sv, so jsonb_array_length returns 0 and
jsonb_array_elements / jsonb_document_contains no longer raise on empty arrays.

Fixes CIP-5156.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Jmn7s3rQQHaix17SvioLg
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Jmn7s3rQQHaix17SvioLg
@changeset-bot

changeset-bot Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b45333d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 12 packages
Name Type
@cipherstash/eql Patch
stash Patch
@cipherstash/stack-prisma Patch
@cipherstash/basic-example Patch
@cipherstash/e2e Patch
@cipherstash/prisma-example Patch
@cipherstash/stack-drizzle Patch
@cipherstash/stack-supabase Patch
@cipherstash/stack Patch
@cipherstash/wizard Patch
@cipherstash/bench Patch
@cipherstash/test-kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

@cipherstash-agent cipherstash-agent self-assigned this Nov 6, 2026
@blacksmith-sh

This comment has been minimized.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Jmn7s3rQQHaix17SvioLg

Copy link
Copy Markdown
Contributor Author

The SQL doc validation check failed because a test comment in v3_jsonb_tests.rs named a private tracker ID. This was this PR's own change. I removed the ID in 3d4c4f1, and test:public_identifiers now passes locally. Waiting on CI to re-run.


Generated by Claude Code

Copy link
Copy Markdown
Contributor Author

Matrix coverage inventory failed because the new v3_jsonb_empty_array_accessors test was missing from tests/sqlx/snapshots/v3_jsonb_tests.txt. This was this PR's own change. I added it in b45333d, in sorted order. Waiting on CI to re-run.


Generated by Claude Code

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants