Skip to content

chore: release candidate for EQL v4 and Stack Encrypt Rust and Go support - #1229

Open
coderdan wants to merge 402 commits into
mainfrom
next
Open

coderdan wants to merge 402 commits into
mainfrom
next

Conversation

@coderdan

Copy link
Copy Markdown
Contributor

Summary

This is the integration branch for a release candidate of EQL v4 and of Stack Encrypt's Rust and Go support. EQL is the SQL that lets PostgreSQL store and search encrypted values; EQL v4 is a second copy of it for values written by Stack Encrypt, the Rust encryption engine behind the Go SDK. The open pull requests for both are merged here first, so they can be tested together before any of them reaches main.

The release version is not decided yet.

Why a branch, not main

Some of this work depends on vitaminc and ore.rs code that is not yet on crates.io, so it pins those crates to a git commit. stack-encrypt and eql-bindings are published crates, and cargo publish drops those git pins, so nothing on this branch can be released until vitaminc 0.6 is published (cipherstash/vitaminc#389, which waits on cipherstash/vitaminc#463). Once it is, the git pins become crates.io versions and this branch merges to main as a normal release.

What lands here, in order

  1. EQL v4: docs(adr): one value model, three encodings in vitaminc, EQL v4 by producer #1139, refactor(eql): write the SQL source with schema and version placeholders #1147, feat(eql): build the eql_v4 bundle beside eql_v3 #1161, feat(eql-bindings): generate EQL v4 bindings and derive Stack Encrypt traits on v4 only #1162, feat(eql-bindings): produce the unordered EQL v4 number, boolean and text types #1163, feat(eql-bindings): produce EQL v4 TextMatch from Stack Encrypt match terms #1164, test(golang): prove the EQL v4 types from Go, against Rust and PostgreSQL #1165. Uses vitaminc 0.5.1 from crates.io only.
  2. Stack Encrypt operators: docs(adr): ADR-0009, operators select the index and a query term is not the stored term #1177, feat(stack-encrypt)!: a query names an operator, not an index #1190, feat(stack-encrypt): verify a match query's rows after decrypt #1191, feat(stack-encrypt): size a match query's fetch with target_limit #1192, feat(stack-encrypt): store short TextMatch text as an empty filter, refuse only short queries #1206, feat(stack-encrypt): ordering operators Lt, Lte, Gt, Gte and Between, and remove query_index #1208, feat(stack-encrypt): JSON operators Contains, ContainedBy and AtPath #1209, feat(stack-encrypt)!: move the stack crates, the guests and the Go module onto vitaminc ADR 0001 #1213, feat(stack-encrypt)!: derive terms through vitaminc-normalize and walk dynamic values as Plaintext #1214, feat(stack-encrypt): query a plan field by operator through the guest, with verify and target_limit as exports #1215, feat(golang)!: generate one query method per operator, with Verify and TargetLimit on a matches query #1216. Before it lands, feat(stack-encrypt)!: move the stack crates, the guests and the Go module onto vitaminc ADR 0001 #1213 moves its vitaminc pin from the deleted branch feat/aead-remove-legacy-traits to one commit on vitaminc main, and takes vitaminc's breaking changes since then.
  3. Not planned yet: the KMS stack (feat(stack-kms): ZeroKMS as a vitaminc key provider (CIP-3965) #1084, feat(stack-encrypt)!: keysets resolve through a KeysetRegistry, and sealed leaves move to format 2 (CIP-4140) #1085, feat(stack-encrypt): run vendor KMS backends through a static keyset registry (CIP-3965) #1083). It is built on a vitaminc commit that is no longer on any branch, and it needs vitaminc's KMS work rebased first.

Rules for this branch

  • Pin vitaminc and ore.rs with rev, never branch. A branch is deleted when its stack merges.
  • Use one vitaminc commit in every Cargo workspace that pins one: the root, both Go guests, packages/eql and packages/stack-encrypt/fuzz. Two commits mean two copies of vitaminc's traits, and the code stops compiling.

Changes

  • One empty commit, so the branch has a pull request. The stacks above add the content.

Verification

  • next was created from main at 2a70a47. Nothing has been built yet, because nothing has changed.

Related

@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 741 files, which is 641 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

Usage-priced reviews support at most 300 files.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI; Enforced overrides: Organization
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4d54743f-8137-478f-a7ff-aa40038fa98f
Commits

Reviewing files that changed from the base of the PR and between 8d48bbc and b104982.

Files ignored due to path filters: 10
  • Cargo.lock is excluded by !**/*.lock
  • languages/golang/auth/guest/Cargo.lock is excluded by !**/*.lock
  • languages/golang/encrypt/guest/Cargo.lock is excluded by !**/*.lock
  • languages/golang/go.sum is excluded by !**/*.sum
  • languages/typescript/packages/protect-ffi/Cargo.lock is excluded by !**/*.lock
  • packages/eql/Cargo.lock is excluded by !**/*.lock
  • packages/eql/tests/timing/ore_block_v2/ctgen/Cargo.lock is excluded by !**/*.lock
  • packages/stack-auth/fuzz/Cargo.lock is excluded by !**/*.lock
  • packages/stack-encrypt/fuzz/Cargo.lock is excluded by !**/*.lock
  • packages/stack-kms/fuzz/Cargo.lock is excluded by !**/*.lock
Files selected for processing: 741
  • .cargo/mutants.toml
  • .changeset/chacha20-0-10-2.md
  • .changeset/eql-bindings-optional-storage-only.md
  • .changeset/eql-json-tree-domain.md
  • .changeset/eql-json-tree-ordinal-chain.md
  • .changeset/eql-json-tree-planner-and-leakage.md
  • .changeset/eql-json-tree-walk-and-projection.md
  • .changeset/eql-lints-own-domains.md
  • .changeset/eql-plan-field-targets.md
  • .changeset/eql-target-match-options.md
  • .changeset/eql-text-equality-transcoding.md
  • .changeset/eql-v4-bindings.md
  • .changeset/eql-v4-block-ore-types.md
  • .changeset/eql-v4-date-timestamp-numeric.md
  • .changeset/eql-v4-order-term-shape.md
  • .changeset/eql-v4-ordered-date-timestamp-numeric.md
  • .changeset/eql-v4-ordered-ope-types.md
  • .changeset/eql-v4-smallint.md
  • .changeset/eql-v4-text-search-optional-terms.md
  • .github/actions/build-ffi-binding/action.yml
  • .github/copilot-instructions.md
  • .github/dependabot.yml
  • .github/workflows/fuzz.yml
  • .github/workflows/integration-drizzle.yml
  • .github/workflows/integration-prisma-next.yml
  • .github/workflows/integration-protect-ffi.yml
  • .github/workflows/integration-supabase.yml
  • .github/workflows/prisma-example-readme-e2e.yml
  • .github/workflows/prisma-next-e2e.yml
  • .github/workflows/test-eql.yml
  • .github/workflows/tests-bench.yml
  • .github/workflows/tests-golang.yml
  • .github/workflows/tests-rust.yml
  • .github/workflows/tests.yml
  • AGENTS.md
  • Cargo.toml
  • biome.json
  • docs/adr/0002-one-value-model-three-encodings-and-eql-v4-by-producer.md
  • docs/fuzzing.md
  • docs/plans/2026-10-04-plan-builder.md
  • docs/plans/2026-10-11-order-and-equality-terms-layering.md
  • docs/plans/2026-10-17-json-tree-index.md
  • docs/plans/2026-10-17-json-tree-index/containment-oracle.sql
  • docs/plans/2026-10-17-json-tree-index/jsonb-semantics.sql
  • docs/plans/2026-10-17-json-tree-index/token-chain.sql
  • languages/golang/CHANGELOG.md
  • languages/golang/auth/cancel_test.go
  • languages/golang/auth/doc.go
  • languages/golang/auth/guest.go
  • languages/golang/auth/guest/Cargo.toml
  • languages/golang/auth/guest/src/lib.rs
  • languages/golang/auth/guest/src/ops.rs
  • languages/golang/auth/guest/tests/leak.rs
  • languages/golang/auth/store.go
  • languages/golang/auth/strategy.go
  • languages/golang/auth/transport.go
  • languages/golang/cmd/stashgen/README.md
  • languages/golang/cmd/stashgen/main_test.go
  • languages/golang/encrypt/README.md
  • languages/golang/encrypt/cancel_test.go
  • languages/golang/encrypt/checker.go
  • languages/golang/encrypt/ciphertext.go
  • languages/golang/encrypt/client.go
  • languages/golang/encrypt/context_field_test.go
  • languages/golang/encrypt/diagnostic_test.go
  • languages/golang/encrypt/doc.go
  • languages/golang/encrypt/eql/eql.go
  • languages/golang/encrypt/eql/eql_gen.go
  • languages/golang/encrypt/eql/eql_test.go
  • languages/golang/encrypt/eql_order_postgres_test.go
  • languages/golang/encrypt/eql_postgres_test.go
  • languages/golang/encrypt/eql_test.go
  • languages/golang/encrypt/eql_v4_ledger_test.go
  • languages/golang/encrypt/eql_v4_order_test.go
  • languages/golang/encrypt/eql_v4_smallint_test.go
  • languages/golang/encrypt/eql_v4_test.go
  • languages/golang/encrypt/eql_v4_text_search_test.go
  • languages/golang/encrypt/errors_test.go
  • languages/golang/encrypt/example/README.md
  • languages/golang/encrypt/example/main.go
  • languages/golang/encrypt/example/user_stash.go
  • languages/golang/encrypt/export_test.go
  • languages/golang/encrypt/fixture_test.go
  • languages/golang/encrypt/generated_paths_test.go
  • languages/golang/encrypt/gensupport/codec.go
  • languages/golang/encrypt/gensupport/convert.go
  • languages/golang/encrypt/gensupport/declaration.go
  • languages/golang/encrypt/gensupport/field.go
  • languages/golang/encrypt/gensupport/gensupport_internal_test.go
  • languages/golang/encrypt/gensupport/widen.go
  • languages/golang/encrypt/guest.go
  • languages/golang/encrypt/guest/Cargo.toml
  • languages/golang/encrypt/guest/src/abi.rs
  • languages/golang/encrypt/guest/src/config.rs
  • languages/golang/encrypt/guest/src/deterministic.rs
  • languages/golang/encrypt/guest/src/host.rs
  • languages/golang/encrypt/guest/src/io.rs
  • languages/golang/encrypt/guest/src/lib.rs
  • languages/golang/encrypt/guest/src/ops.rs
  • languages/golang/encrypt/guest/src/options.rs
  • languages/golang/encrypt/guest/src/status.rs
  • languages/golang/encrypt/guest/src/targets.rs
  • languages/golang/encrypt/guest/src/test_frame.rs
  • languages/golang/encrypt/guest/tests/leak.rs
  • languages/golang/encrypt/guest/tests/native_ops.rs
  • languages/golang/encrypt/guest/tests/support/mod.rs
  • languages/golang/encrypt/guest_test.go
  • languages/golang/encrypt/internal/testpolicy/member_stash.go
  • languages/golang/encrypt/internal/testusers/account_stash.go
  • languages/golang/encrypt/internal/testusers/birthday_stash.go
  • languages/golang/encrypt/internal/testusers/contact_stash.go
  • languages/golang/encrypt/internal/testusers/directory.go
  • languages/golang/encrypt/internal/testusers/entry_stash.go
  • languages/golang/encrypt/internal/testusers/kinds.go
  • languages/golang/encrypt/internal/testusers/kinds_stash.go
  • languages/golang/encrypt/internal/testusers/ledger.go
  • languages/golang/encrypt/internal/testusers/ledger_stash.go
  • languages/golang/encrypt/internal/testusers/lookup_stash.go
  • languages/golang/encrypt/internal/testusers/memberstash_stash.go
  • languages/golang/encrypt/internal/testusers/note_stash.go
  • languages/golang/encrypt/internal/testusers/people.go
  • languages/golang/encrypt/internal/testusers/person_stash.go
  • languages/golang/encrypt/internal/testusers/probe_stash.go
  • languages/golang/encrypt/internal/testusers/profile_stash.go
  • languages/golang/encrypt/internal/testusers/profiles.go
  • languages/golang/encrypt/internal/testusers/queryprofile_stash.go
  • languages/golang/encrypt/internal/testusers/ranking.go
  • languages/golang/encrypt/internal/testusers/ranking_stash.go
  • languages/golang/encrypt/internal/testusers/tally.go
  • languages/golang/encrypt/internal/testusers/tally_stash.go
  • languages/golang/encrypt/internal/testusers/user_stash.go
  • languages/golang/encrypt/internal/testusers/users.go
  • languages/golang/encrypt/internal/testusers/valuekinds_stash.go
  • languages/golang/encrypt/internal/testusers/widened_stash.go
  • languages/golang/encrypt/kinds_test.go
  • languages/golang/encrypt/live_test.go
  • languages/golang/encrypt/locate_test.go
  • languages/golang/encrypt/memory_test.go
  • languages/golang/encrypt/null_test.go
  • languages/golang/encrypt/order_test.go
  • languages/golang/encrypt/postgres_test.go
  • languages/golang/encrypt/query.go
  • languages/golang/encrypt/query_test.go
  • languages/golang/encrypt/records.go
  • languages/golang/encrypt/roundtrip_test.go
  • languages/golang/encrypt/step.go
  • languages/golang/encrypt/step_test.go
  • languages/golang/encrypt/targets_test.go
  • languages/golang/encrypt/transport.go
  • languages/golang/encrypt/unit_test.go
  • languages/golang/encrypt/value_kinds_test.go
  • languages/golang/encrypt/values.go
  • languages/golang/encrypt/widened_test.go
  • languages/golang/go.mod
  • languages/golang/internal/guest/call.go
  • languages/golang/internal/guest/errors.go
  • languages/golang/internal/guest/lock.go
  • languages/golang/internal/guest/lock_test.go
  • languages/golang/internal/guest/status.go
  • languages/golang/internal/record/record.go
  • languages/golang/stashgen/declaration.go
  • languages/golang/stashgen/emit.go
  • languages/golang/stashgen/engine.go
  • languages/golang/stashgen/enginetest/enginetest.go
  • languages/golang/stashgen/generate.go
  • languages/golang/stashgen/golden_test.go
  • languages/golang/stashgen/lower_test.go
  • languages/golang/stashgen/policy.go
  • languages/golang/stashgen/read.go
  • languages/golang/stashgen/refusal_test.go
  • languages/golang/stashgen/tag.go
  • languages/golang/stashgen/testdata/cases/accounts/account_stash.go.golden
  • languages/golang/stashgen/testdata/cases/contacts/contacts.go
  • languages/golang/stashgen/testdata/cases/contacts/contactstash_stash.go.golden
  • languages/golang/stashgen/testdata/cases/directory/directory.go
  • languages/golang/stashgen/testdata/cases/directory/entry_stash.go.golden
  • languages/golang/stashgen/testdata/cases/directory/go.mod
  • languages/golang/stashgen/testdata/cases/embedded/patient_stash.go.golden
  • languages/golang/stashgen/testdata/cases/foreign/individualstash_stash.go.golden
  • languages/golang/stashgen/testdata/cases/orders/order_stash.go.golden
  • languages/golang/stashgen/testdata/cases/orders/refund_stash.go.golden
  • languages/golang/stashgen/testdata/cases/tenants/note_stash.go.golden
  • languages/golang/stashgen/testdata/cases/users/model.go
  • languages/golang/stashgen/testdata/cases/users/user_stash.go.golden
  • languages/golang/stashgen/testdata/policy_individual_stash.go.golden
  • languages/golang/stashgen/testdata/stubsdk/encrypt/encrypt.go
  • languages/golang/stashgen/testdata/stubsdk/encrypt/eql/eql.go
  • languages/golang/stashgen/testdata/stubsdk/encrypt/gensupport/gensupport.go
  • mise.toml
  • packages/eql/.gitattributes
  • packages/eql/.gitignore
  • packages/eql/AGENTS.md
  • packages/eql/crates/eql-bindings/CHANGELOG.md
  • packages/eql/crates/eql-bindings/Cargo.toml
  • packages/eql/crates/eql-bindings/README.md
  • packages/eql/crates/eql-bindings/src/encoding.rs
  • packages/eql/crates/eql-bindings/src/encryption.rs
  • packages/eql/crates/eql-bindings/src/encryption/example.rs
  • packages/eql/crates/eql-bindings/src/encryption/query.rs
  • packages/eql/crates/eql-bindings/src/encryption/query_example.rs
  • packages/eql/crates/eql-bindings/src/encryption/targets.rs
  • packages/eql/crates/eql-bindings/src/lib.rs
  • packages/eql/crates/eql-bindings/src/v3/bigint.rs
  • packages/eql/crates/eql-bindings/src/v3/boolean.rs
  • packages/eql/crates/eql-bindings/src/v3/date.rs
  • packages/eql/crates/eql-bindings/src/v3/domain_type.rs
  • packages/eql/crates/eql-bindings/src/v3/double.rs
  • packages/eql/crates/eql-bindings/src/v3/integer.rs
  • packages/eql/crates/eql-bindings/src/v3/json_storage.rs
  • packages/eql/crates/eql-bindings/src/v3/mod.rs
  • packages/eql/crates/eql-bindings/src/v3/numeric.rs
  • packages/eql/crates/eql-bindings/src/v3/real.rs
  • packages/eql/crates/eql-bindings/src/v3/smallint.rs
  • packages/eql/crates/eql-bindings/src/v3/targets.rs
  • packages/eql/crates/eql-bindings/src/v3/text.rs
  • packages/eql/crates/eql-bindings/src/v3/timestamp.rs
  • packages/eql/crates/eql-bindings/src/v4/answers.rs
  • packages/eql/crates/eql-bindings/src/v4/bigint.rs
  • packages/eql/crates/eql-bindings/src/v4/boolean.rs
  • packages/eql/crates/eql-bindings/src/v4/date.rs
  • packages/eql/crates/eql-bindings/src/v4/double.rs
  • packages/eql/crates/eql-bindings/src/v4/integer.rs
  • packages/eql/crates/eql-bindings/src/v4/inventory.rs
  • packages/eql/crates/eql-bindings/src/v4/json.rs
  • packages/eql/crates/eql-bindings/src/v4/json_tree.rs
  • packages/eql/crates/eql-bindings/src/v4/mod.rs
  • packages/eql/crates/eql-bindings/src/v4/numeric.rs
  • packages/eql/crates/eql-bindings/src/v4/plaintext.rs
  • packages/eql/crates/eql-bindings/src/v4/real.rs
  • packages/eql/crates/eql-bindings/src/v4/smallint.rs
  • packages/eql/crates/eql-bindings/src/v4/targets.rs
  • packages/eql/crates/eql-bindings/src/v4/term_formats.rs
  • packages/eql/crates/eql-bindings/src/v4/text.rs
  • packages/eql/crates/eql-bindings/src/v4/timestamp.rs
  • packages/eql/crates/eql-bindings/tests/v4_inventory.rs
  • packages/eql/crates/eql-codegen/src/bindings.rs
  • packages/eql/crates/eql-codegen/src/consts.rs
  • packages/eql/crates/eql-codegen/src/context.rs
  • packages/eql/crates/eql-codegen/src/generate.rs
  • packages/eql/crates/eql-codegen/src/go_eql.rs
  • packages/eql/crates/eql-codegen/src/lib.rs
  • packages/eql/crates/eql-codegen/src/main.rs
  • packages/eql/crates/eql-codegen/src/range.rs
  • packages/eql/crates/eql-codegen/src/render.rs
  • packages/eql/crates/eql-codegen/src/targets.rs
  • packages/eql/crates/eql-codegen/templates/functions/extractor.sql.j2
  • packages/eql/crates/eql-codegen/templates/ore_fallback.sql.j2
  • packages/eql/crates/eql-codegen/templates/query_types.sql.j2
  • packages/eql/crates/eql-codegen/templates/range_functions.sql.j2
  • packages/eql/crates/eql-codegen/templates/range_types.sql.j2
  • packages/eql/crates/eql-codegen/templates/types.sql.j2
  • packages/eql/crates/eql-codegen/tests/bindings_parity.rs
  • packages/eql/crates/eql-codegen/tests/cli.rs
  • packages/eql/crates/eql-domains/src/lib.rs
  • packages/eql/crates/eql-domains/src/spec.rs
  • packages/eql/crates/eql-domains/src/term.rs
  • packages/eql/crates/eql-domains/src/tests.rs
  • packages/eql/docs/README.md
  • packages/eql/docs/reference/adding-a-scalar-encrypted-domain-type.md
  • packages/eql/docs/reference/catalog-driven-architecture.md
  • packages/eql/docs/reference/eql-functions.md
  • packages/eql/docs/reference/json-tree-leakage.md
  • packages/eql/docs/upgrading/v3.1.md
  • packages/eql/mise.toml
  • packages/eql/src/v3/aggregates.sql
  • packages/eql/src/v3/common.sql
  • packages/eql/src/v3/crypto.sql
  • packages/eql/src/v3/json/aggregates.sql
  • packages/eql/src/v3/json/blockers.sql
  • packages/eql/src/v3/json/functions.sql
  • packages/eql/src/v3/json/operators.sql
  • packages/eql/src/v3/json/types.sql
  • packages/eql/src/v3/json_tree/blockers.sql
  • packages/eql/src/v3/json_tree/functions.sql
  • packages/eql/src/v3/json_tree/operators.sql
  • packages/eql/src/v3/json_tree/types.sql
  • packages/eql/src/v3/lint/lints.sql
  • packages/eql/src/v3/scalars/bigint/bigint_eq_functions.sql
  • packages/eql/src/v3/scalars/bigint/bigint_eq_operators.sql
  • packages/eql/src/v3/scalars/bigint/bigint_functions.sql
  • packages/eql/src/v3/scalars/bigint/bigint_operators.sql
  • packages/eql/src/v3/scalars/bigint/bigint_ord_aggregates.sql
  • packages/eql/src/v3/scalars/bigint/bigint_ord_functions.sql
  • packages/eql/src/v3/scalars/bigint/bigint_ord_ope_aggregates.sql
  • packages/eql/src/v3/scalars/bigint/bigint_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/bigint/bigint_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/bigint/bigint_ord_operators.sql
  • packages/eql/src/v3/scalars/bigint/bigint_ord_ore_aggregates.sql
  • packages/eql/src/v3/scalars/bigint/bigint_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/bigint/bigint_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/bigint/bigint_types.sql
  • packages/eql/src/v3/scalars/bigint/json_entry_bigint_functions.sql
  • packages/eql/src/v3/scalars/bigint/json_entry_bigint_operators.sql
  • packages/eql/src/v3/scalars/bigint/query_bigint_eq_functions.sql
  • packages/eql/src/v3/scalars/bigint/query_bigint_eq_operators.sql
  • packages/eql/src/v3/scalars/bigint/query_bigint_ord_functions.sql
  • packages/eql/src/v3/scalars/bigint/query_bigint_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/bigint/query_bigint_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/bigint/query_bigint_ord_operators.sql
  • packages/eql/src/v3/scalars/bigint/query_bigint_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/bigint/query_bigint_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/bigint/query_bigint_range_functions.sql
  • packages/eql/src/v3/scalars/bigint/query_bigint_range_types.sql
  • packages/eql/src/v3/scalars/bigint/query_bigint_types.sql
  • packages/eql/src/v3/scalars/boolean/boolean_functions.sql
  • packages/eql/src/v3/scalars/boolean/boolean_operators.sql
  • packages/eql/src/v3/scalars/boolean/boolean_types.sql
  • packages/eql/src/v3/scalars/date/date_eq_functions.sql
  • packages/eql/src/v3/scalars/date/date_eq_operators.sql
  • packages/eql/src/v3/scalars/date/date_functions.sql
  • packages/eql/src/v3/scalars/date/date_operators.sql
  • packages/eql/src/v3/scalars/date/date_ord_aggregates.sql
  • packages/eql/src/v3/scalars/date/date_ord_functions.sql
  • packages/eql/src/v3/scalars/date/date_ord_ope_aggregates.sql
  • packages/eql/src/v3/scalars/date/date_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/date/date_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/date/date_ord_operators.sql
  • packages/eql/src/v3/scalars/date/date_ord_ore_aggregates.sql
  • packages/eql/src/v3/scalars/date/date_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/date/date_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/date/date_types.sql
  • packages/eql/src/v3/scalars/date/json_entry_date_functions.sql
  • packages/eql/src/v3/scalars/date/json_entry_date_operators.sql
  • packages/eql/src/v3/scalars/date/query_date_eq_functions.sql
  • packages/eql/src/v3/scalars/date/query_date_eq_operators.sql
  • packages/eql/src/v3/scalars/date/query_date_ord_functions.sql
  • packages/eql/src/v3/scalars/date/query_date_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/date/query_date_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/date/query_date_ord_operators.sql
  • packages/eql/src/v3/scalars/date/query_date_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/date/query_date_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/date/query_date_range_functions.sql
  • packages/eql/src/v3/scalars/date/query_date_range_types.sql
  • packages/eql/src/v3/scalars/date/query_date_types.sql
  • packages/eql/src/v3/scalars/double/double_eq_functions.sql
  • packages/eql/src/v3/scalars/double/double_eq_operators.sql
  • packages/eql/src/v3/scalars/double/double_functions.sql
  • packages/eql/src/v3/scalars/double/double_operators.sql
  • packages/eql/src/v3/scalars/double/double_ord_aggregates.sql
  • packages/eql/src/v3/scalars/double/double_ord_functions.sql
  • packages/eql/src/v3/scalars/double/double_ord_ope_aggregates.sql
  • packages/eql/src/v3/scalars/double/double_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/double/double_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/double/double_ord_operators.sql
  • packages/eql/src/v3/scalars/double/double_ord_ore_aggregates.sql
  • packages/eql/src/v3/scalars/double/double_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/double/double_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/double/double_types.sql
  • packages/eql/src/v3/scalars/double/json_entry_double_functions.sql
  • packages/eql/src/v3/scalars/double/json_entry_double_operators.sql
  • packages/eql/src/v3/scalars/double/query_double_eq_functions.sql
  • packages/eql/src/v3/scalars/double/query_double_eq_operators.sql
  • packages/eql/src/v3/scalars/double/query_double_ord_functions.sql
  • packages/eql/src/v3/scalars/double/query_double_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/double/query_double_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/double/query_double_ord_operators.sql
  • packages/eql/src/v3/scalars/double/query_double_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/double/query_double_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/double/query_double_range_functions.sql
  • packages/eql/src/v3/scalars/double/query_double_range_types.sql
  • packages/eql/src/v3/scalars/double/query_double_types.sql
  • packages/eql/src/v3/scalars/functions.sql
  • packages/eql/src/v3/scalars/integer/integer_eq_functions.sql
  • packages/eql/src/v3/scalars/integer/integer_eq_operators.sql
  • packages/eql/src/v3/scalars/integer/integer_functions.sql
  • packages/eql/src/v3/scalars/integer/integer_operators.sql
  • packages/eql/src/v3/scalars/integer/integer_ord_aggregates.sql
  • packages/eql/src/v3/scalars/integer/integer_ord_functions.sql
  • packages/eql/src/v3/scalars/integer/integer_ord_ope_aggregates.sql
  • packages/eql/src/v3/scalars/integer/integer_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/integer/integer_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/integer/integer_ord_operators.sql
  • packages/eql/src/v3/scalars/integer/integer_ord_ore_aggregates.sql
  • packages/eql/src/v3/scalars/integer/integer_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/integer/integer_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/integer/integer_types.sql
  • packages/eql/src/v3/scalars/integer/json_entry_integer_functions.sql
  • packages/eql/src/v3/scalars/integer/json_entry_integer_operators.sql
  • packages/eql/src/v3/scalars/integer/query_integer_eq_functions.sql
  • packages/eql/src/v3/scalars/integer/query_integer_eq_operators.sql
  • packages/eql/src/v3/scalars/integer/query_integer_ord_functions.sql
  • packages/eql/src/v3/scalars/integer/query_integer_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/integer/query_integer_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/integer/query_integer_ord_operators.sql
  • packages/eql/src/v3/scalars/integer/query_integer_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/integer/query_integer_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/integer/query_integer_range_functions.sql
  • packages/eql/src/v3/scalars/integer/query_integer_range_types.sql
  • packages/eql/src/v3/scalars/integer/query_integer_types.sql
  • packages/eql/src/v3/scalars/json/json_functions.sql
  • packages/eql/src/v3/scalars/json/json_operators.sql
  • packages/eql/src/v3/scalars/json/json_types.sql
  • packages/eql/src/v3/scalars/numeric/json_entry_numeric_functions.sql
  • packages/eql/src/v3/scalars/numeric/json_entry_numeric_operators.sql
  • packages/eql/src/v3/scalars/numeric/numeric_eq_functions.sql
  • packages/eql/src/v3/scalars/numeric/numeric_eq_operators.sql
  • packages/eql/src/v3/scalars/numeric/numeric_functions.sql
  • packages/eql/src/v3/scalars/numeric/numeric_operators.sql
  • packages/eql/src/v3/scalars/numeric/numeric_ord_aggregates.sql
  • packages/eql/src/v3/scalars/numeric/numeric_ord_functions.sql
  • packages/eql/src/v3/scalars/numeric/numeric_ord_ope_aggregates.sql
  • packages/eql/src/v3/scalars/numeric/numeric_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/numeric/numeric_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/numeric/numeric_ord_operators.sql
  • packages/eql/src/v3/scalars/numeric/numeric_ord_ore_aggregates.sql
  • packages/eql/src/v3/scalars/numeric/numeric_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/numeric/numeric_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/numeric/numeric_types.sql
  • packages/eql/src/v3/scalars/numeric/query_numeric_eq_functions.sql
  • packages/eql/src/v3/scalars/numeric/query_numeric_eq_operators.sql
  • packages/eql/src/v3/scalars/numeric/query_numeric_ord_functions.sql
  • packages/eql/src/v3/scalars/numeric/query_numeric_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/numeric/query_numeric_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/numeric/query_numeric_ord_operators.sql
  • packages/eql/src/v3/scalars/numeric/query_numeric_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/numeric/query_numeric_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/numeric/query_numeric_range_functions.sql
  • packages/eql/src/v3/scalars/numeric/query_numeric_range_types.sql
  • packages/eql/src/v3/scalars/numeric/query_numeric_types.sql
  • packages/eql/src/v3/scalars/ore_fallback.sql
  • packages/eql/src/v3/scalars/real/json_entry_real_functions.sql
  • packages/eql/src/v3/scalars/real/json_entry_real_operators.sql
  • packages/eql/src/v3/scalars/real/query_real_eq_functions.sql
  • packages/eql/src/v3/scalars/real/query_real_eq_operators.sql
  • packages/eql/src/v3/scalars/real/query_real_ord_functions.sql
  • packages/eql/src/v3/scalars/real/query_real_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/real/query_real_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/real/query_real_ord_operators.sql
  • packages/eql/src/v3/scalars/real/query_real_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/real/query_real_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/real/query_real_range_functions.sql
  • packages/eql/src/v3/scalars/real/query_real_range_types.sql
  • packages/eql/src/v3/scalars/real/query_real_types.sql
  • packages/eql/src/v3/scalars/real/real_eq_functions.sql
  • packages/eql/src/v3/scalars/real/real_eq_operators.sql
  • packages/eql/src/v3/scalars/real/real_functions.sql
  • packages/eql/src/v3/scalars/real/real_operators.sql
  • packages/eql/src/v3/scalars/real/real_ord_aggregates.sql
  • packages/eql/src/v3/scalars/real/real_ord_functions.sql
  • packages/eql/src/v3/scalars/real/real_ord_ope_aggregates.sql
  • packages/eql/src/v3/scalars/real/real_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/real/real_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/real/real_ord_operators.sql
  • packages/eql/src/v3/scalars/real/real_ord_ore_aggregates.sql
  • packages/eql/src/v3/scalars/real/real_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/real/real_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/real/real_types.sql
  • packages/eql/src/v3/scalars/smallint/json_entry_smallint_functions.sql
  • packages/eql/src/v3/scalars/smallint/json_entry_smallint_operators.sql
  • packages/eql/src/v3/scalars/smallint/query_smallint_eq_functions.sql
  • packages/eql/src/v3/scalars/smallint/query_smallint_eq_operators.sql
  • packages/eql/src/v3/scalars/smallint/query_smallint_ord_functions.sql
  • packages/eql/src/v3/scalars/smallint/query_smallint_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/smallint/query_smallint_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/smallint/query_smallint_ord_operators.sql
  • packages/eql/src/v3/scalars/smallint/query_smallint_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/smallint/query_smallint_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/smallint/query_smallint_range_functions.sql
  • packages/eql/src/v3/scalars/smallint/query_smallint_range_types.sql
  • packages/eql/src/v3/scalars/smallint/query_smallint_types.sql
  • packages/eql/src/v3/scalars/smallint/smallint_eq_functions.sql
  • packages/eql/src/v3/scalars/smallint/smallint_eq_operators.sql
  • packages/eql/src/v3/scalars/smallint/smallint_functions.sql
  • packages/eql/src/v3/scalars/smallint/smallint_operators.sql
  • packages/eql/src/v3/scalars/smallint/smallint_ord_aggregates.sql
  • packages/eql/src/v3/scalars/smallint/smallint_ord_functions.sql
  • packages/eql/src/v3/scalars/smallint/smallint_ord_ope_aggregates.sql
  • packages/eql/src/v3/scalars/smallint/smallint_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/smallint/smallint_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/smallint/smallint_ord_operators.sql
  • packages/eql/src/v3/scalars/smallint/smallint_ord_ore_aggregates.sql
  • packages/eql/src/v3/scalars/smallint/smallint_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/smallint/smallint_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/smallint/smallint_types.sql
  • packages/eql/src/v3/scalars/text/json_entry_text_functions.sql
  • packages/eql/src/v3/scalars/text/json_entry_text_operators.sql
  • packages/eql/src/v3/scalars/text/query_text_eq_functions.sql
  • packages/eql/src/v3/scalars/text/query_text_eq_operators.sql
  • packages/eql/src/v3/scalars/text/query_text_match_functions.sql
  • packages/eql/src/v3/scalars/text/query_text_match_operators.sql
  • packages/eql/src/v3/scalars/text/query_text_ord_functions.sql
  • packages/eql/src/v3/scalars/text/query_text_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/text/query_text_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/text/query_text_ord_operators.sql
  • packages/eql/src/v3/scalars/text/query_text_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/text/query_text_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/text/query_text_range_functions.sql
  • packages/eql/src/v3/scalars/text/query_text_range_types.sql
  • packages/eql/src/v3/scalars/text/query_text_search_functions.sql
  • packages/eql/src/v3/scalars/text/query_text_search_operators.sql
  • packages/eql/src/v3/scalars/text/query_text_search_ore_functions.sql
  • packages/eql/src/v3/scalars/text/query_text_search_ore_operators.sql
  • packages/eql/src/v3/scalars/text/query_text_types.sql
  • packages/eql/src/v3/scalars/text/text_eq_functions.sql
  • packages/eql/src/v3/scalars/text/text_eq_operators.sql
  • packages/eql/src/v3/scalars/text/text_functions.sql
  • packages/eql/src/v3/scalars/text/text_match_functions.sql
  • packages/eql/src/v3/scalars/text/text_match_operators.sql
  • packages/eql/src/v3/scalars/text/text_operators.sql
  • packages/eql/src/v3/scalars/text/text_ord_aggregates.sql
  • packages/eql/src/v3/scalars/text/text_ord_functions.sql
  • packages/eql/src/v3/scalars/text/text_ord_ope_aggregates.sql
  • packages/eql/src/v3/scalars/text/text_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/text/text_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/text/text_ord_operators.sql
  • packages/eql/src/v3/scalars/text/text_ord_ore_aggregates.sql
  • packages/eql/src/v3/scalars/text/text_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/text/text_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/text/text_search_aggregates.sql
  • packages/eql/src/v3/scalars/text/text_search_functions.sql
  • packages/eql/src/v3/scalars/text/text_search_operators.sql
  • packages/eql/src/v3/scalars/text/text_search_ore_aggregates.sql
  • packages/eql/src/v3/scalars/text/text_search_ore_functions.sql
  • packages/eql/src/v3/scalars/text/text_search_ore_operators.sql
  • packages/eql/src/v3/scalars/text/text_types.sql
  • packages/eql/src/v3/scalars/timestamp/json_entry_timestamp_functions.sql
  • packages/eql/src/v3/scalars/timestamp/json_entry_timestamp_operators.sql
  • packages/eql/src/v3/scalars/timestamp/query_timestamp_eq_functions.sql
  • packages/eql/src/v3/scalars/timestamp/query_timestamp_eq_operators.sql
  • packages/eql/src/v3/scalars/timestamp/query_timestamp_ord_functions.sql
  • packages/eql/src/v3/scalars/timestamp/query_timestamp_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/timestamp/query_timestamp_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/timestamp/query_timestamp_ord_operators.sql
  • packages/eql/src/v3/scalars/timestamp/query_timestamp_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/timestamp/query_timestamp_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/timestamp/query_timestamp_range_functions.sql
  • packages/eql/src/v3/scalars/timestamp/query_timestamp_range_types.sql
  • packages/eql/src/v3/scalars/timestamp/query_timestamp_types.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_eq_functions.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_eq_operators.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_functions.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_operators.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_ord_aggregates.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_ord_functions.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_ord_ope_aggregates.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_ord_ope_functions.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_ord_ope_operators.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_ord_operators.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_ord_ore_aggregates.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_ord_ore_functions.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_ord_ore_operators.sql
  • packages/eql/src/v3/scalars/timestamp/timestamp_types.sql
  • packages/eql/src/v3/schema.sql
  • packages/eql/src/v3/sem/bloom_filter/functions.sql
  • packages/eql/src/v3/sem/bloom_filter/types.sql
  • packages/eql/src/v3/sem/hmac_256/functions.sql
  • packages/eql/src/v3/sem/hmac_256/types.sql
  • packages/eql/src/v3/sem/ope_cllw/functions.sql
  • packages/eql/src/v3/sem/ope_cllw/types.sql
  • packages/eql/src/v3/sem/ore_block_256/functions.sql
  • packages/eql/src/v3/sem/ore_block_256/operator_class.sql
  • packages/eql/src/v3/sem/ore_block_256/operators.sql
  • packages/eql/src/v3/sem/ore_block_256/types.sql
  • packages/eql/src/v3/version.template
  • packages/eql/tasks/build.sh
  • packages/eql/tasks/docs/doxygen-filter.sh
  • packages/eql/tasks/docs/validate/documented-sql.sh
  • packages/eql/tasks/githooks/pre-commit
  • packages/eql/tasks/pin_search_path_v3.sql
  • packages/eql/tasks/schemas-parity.sh
  • packages/eql/tasks/test/docs_v3_grep.sh
  • packages/eql/tasks/test/v4_isolation_selftest.sh
  • packages/eql/tasks/test/verify_installer_complete.sh
  • packages/eql/tasks/test/verify_no_v3_in_v4.sh
  • packages/eql/tasks/test/verify_symbol_order_v3.sh
  • packages/eql/tasks/uninstall-v3.sql
  • packages/eql/tests/encryption/Cargo.toml
  • packages/eql/tests/encryption/fixtures/README.md
  • packages/eql/tests/encryption/fixtures/stored_v4_rows_v1.json
  • packages/eql/tests/encryption/fixtures/text_eq_query.json
  • packages/eql/tests/encryption/fixtures/v4_ledger_queries.json
  • packages/eql/tests/encryption/fixtures/v4_ledger_rows.json
  • packages/eql/tests/encryption/fixtures/v4_ordered_queries.json
  • packages/eql/tests/encryption/fixtures/v4_ordered_rows.json
  • packages/eql/tests/encryption/fixtures/v4_queries.json
  • packages/eql/tests/encryption/fixtures/v4_rows.json
  • packages/eql/tests/encryption/fixtures/v4_smallint_rows.json
  • packages/eql/tests/encryption/tests/common/mod.rs
  • packages/eql/tests/encryption/tests/heap_hygiene.rs
  • packages/eql/tests/encryption/tests/json_tree.rs
  • packages/eql/tests/encryption/tests/targets.rs
  • packages/eql/tests/encryption/tests/text_eq.rs
  • packages/eql/tests/encryption/tests/typed_queries.rs
  • packages/eql/tests/encryption/tests/v4_date_time_numeric.rs
  • packages/eql/tests/encryption/tests/v4_order.rs
  • packages/eql/tests/encryption/tests/v4_ore_block.rs
  • packages/eql/tests/encryption/tests/v4_range.rs
  • packages/eql/tests/encryption/tests/v4_text_search.rs
  • packages/eql/tests/encryption/tests/v4_types.rs
  • packages/eql/tests/sqlx/tests/v3_v4_coexistence_tests.rs
  • packages/eql/tests/timing/ore_block_v2/README.md
  • packages/eql/tests/timing/ore_block_v2/ctgen/.gitignore
  • packages/eql/tests/timing/ore_block_v2/ctgen/Cargo.toml
  • packages/eql/tests/timing/ore_block_v2/ctgen/src/main.rs
  • packages/eql/tests/timing/ore_block_v2/harness.sql
  • packages/eql/tests/timing/ore_block_v2/run.sh
  • packages/stack-encrypt-derive/Cargo.toml
  • packages/stack-encrypt-derive/src/lib.rs
  • packages/stack-encrypt/CHANGELOG.md
  • packages/stack-encrypt/CONTEXT.md
  • packages/stack-encrypt/Cargo.toml
  • packages/stack-encrypt/docs/adr/0004-one-context-per-target-threaded-through-the-declaration-tree.md
  • packages/stack-encrypt/docs/adr/0007-bindings-enter-through-a-plan-never-a-second-executor.md
  • packages/stack-encrypt/docs/adr/0009-operators-select-the-index-and-a-query-term-is-not-the-stored-term.md
  • packages/stack-encrypt/docs/adr/0010-what-a-stored-value-authenticates.md
  • packages/stack-encrypt/examples/mixed_user.rs
  • packages/stack-encrypt/examples/search_terms.rs
  • packages/stack-encrypt/fuzz/Cargo.toml
  • packages/stack-encrypt/fuzz/corpus/json_wire_decode/valid-document-open-root
  • packages/stack-encrypt/fuzz/corpus/json_wire_decode/valid-document-sealed-root
  • packages/stack-encrypt/fuzz/corpus/json_wire_decode/valid-header
  • packages/stack-encrypt/fuzz/corpus/json_wire_decode/valid-node
  • packages/stack-encrypt/fuzz/corpus/json_wire_decode/valid-projection
  • packages/stack-encrypt/fuzz/fuzz_targets/check_record.rs
  • packages/stack-encrypt/fuzz/fuzz_targets/json_wire_decode.rs
  • packages/stack-encrypt/fuzz/fuzz_targets/term_decode.rs
  • packages/stack-encrypt/src/cipher.rs
  • packages/stack-encrypt/src/codes.rs
  • packages/stack-encrypt/src/dynamic/context.rs
  • packages/stack-encrypt/src/dynamic/kind.rs
  • packages/stack-encrypt/src/dynamic/mod.rs
  • packages/stack-encrypt/src/dynamic/query.rs
  • packages/stack-encrypt/src/dynamic/record.rs
  • packages/stack-encrypt/src/dynamic/target.rs
  • packages/stack-encrypt/src/dynamic/term.rs
  • packages/stack-encrypt/src/dynamic/test_frame.rs
  • packages/stack-encrypt/src/dynamic/value.rs
  • packages/stack-encrypt/src/dynamic/value_frame.rs
  • packages/stack-encrypt/src/json/derive.rs
  • packages/stack-encrypt/src/json/mod.rs
  • packages/stack-encrypt/src/json/path.rs
  • packages/stack-encrypt/src/json/plain.rs
  • packages/stack-encrypt/src/json/query.rs
  • packages/stack-encrypt/src/lib.rs
  • packages/stack-encrypt/src/op/mod.rs
  • packages/stack-encrypt/src/op/stats.rs
  • packages/stack-encrypt/src/plan/build.rs
  • packages/stack-encrypt/src/plan/chain.rs
  • packages/stack-encrypt/src/plan/error.rs
  • packages/stack-encrypt/src/plan/field_ref.rs
  • packages/stack-encrypt/src/plan/mod.rs
  • packages/stack-encrypt/src/plan/value.rs
  • packages/stack-encrypt/src/sem/mod.rs
  • packages/stack-encrypt/src/sem/tokenize.rs
  • packages/stack-encrypt/src/target/context.rs
  • packages/stack-encrypt/src/target/core.rs
  • packages/stack-encrypt/src/target/index.rs
  • packages/stack-encrypt/src/target/mod.rs
  • packages/stack-encrypt/src/target/operations.rs
  • packages/stack-encrypt/src/target/source.rs
  • packages/stack-encrypt/src/target/transcode.rs
  • packages/stack-encrypt/src/value.rs
  • packages/stack-encrypt/tasks.toml
  • packages/stack-encrypt/tests/common/mod.rs
  • packages/stack-encrypt/tests/derive.rs
  • packages/stack-encrypt/tests/derive_plan.rs
  • packages/stack-encrypt/tests/fixtures/README.md
  • packages/stack-encrypt/tests/fixtures/query_operators.json
  • packages/stack-encrypt/tests/fixtures/record_lowering.json
  • packages/stack-encrypt/tests/fixtures/stored_rows_v1.json
  • packages/stack-encrypt/tests/fixtures/value_kinds.json
  • packages/stack-encrypt/tests/frozen_bytes.rs
  • packages/stack-encrypt/tests/heap_hygiene.rs
  • packages/stack-encrypt/tests/index.rs
  • packages/stack-encrypt/tests/json_index.rs
  • packages/stack-encrypt/tests/op.rs
  • packages/stack-encrypt/tests/ore_block.rs
  • packages/stack-encrypt/tests/plan.rs
  • packages/stack-encrypt/tests/plan_grammar.rs
  • packages/stack-encrypt/tests/query_operators.rs
  • packages/stack-encrypt/tests/record_lowering.rs
  • packages/stack-encrypt/tests/roundtrip.rs
  • packages/stack-encrypt/tests/sem_terms.rs
  • packages/stack-encrypt/tests/source_mode.rs
  • packages/stack-encrypt/tests/stored_rows.rs
  • packages/stack-encrypt/tests/target.rs
  • packages/stack-encrypt/tests/term_bytes.rs
  • packages/stack-encrypt/tests/term_serde.rs
  • packages/stack-encrypt/tests/transcode.rs
  • packages/stack-encrypt/tests/ui.rs
  • packages/stack-encrypt/tests/ui/decrypt_field_not_decryptable.stderr
  • packages/stack-encrypt/tests/ui/drop_record.stderr
  • packages/stack-encrypt/tests/ui/match_in_a_tuple_on_integer.rs
  • packages/stack-encrypt/tests/ui/match_in_a_tuple_on_integer.stderr
  • packages/stack-encrypt/tests/ui/match_on_integer.rs
  • packages/stack-encrypt/tests/ui/match_on_integer.stderr
  • packages/stack-encrypt/tests/ui/op_at_path_inherits_fidelity.rs
  • packages/stack-encrypt/tests/ui/op_at_path_inherits_fidelity.stderr
  • packages/stack-encrypt/tests/ui/op_at_path_not_a_leaf.rs
  • packages/stack-encrypt/tests/ui/op_at_path_not_a_leaf.stderr
  • packages/stack-encrypt/tests/ui/op_between_takes_a_pair.rs
  • packages/stack-encrypt/tests/ui/op_between_takes_a_pair.stderr
  • packages/stack-encrypt/tests/ui/op_case_mismatch.rs
  • packages/stack-encrypt/tests/ui/op_case_mismatch.stderr
  • packages/stack-encrypt/tests/ui/op_inexact_operator_needs_probabilistic.rs
  • packages/stack-encrypt/tests/ui/op_inexact_operator_needs_probabilistic.stderr
  • packages/stack-encrypt/tests/ui/op_json_not_answered.rs
  • packages/stack-encrypt/tests/ui/op_json_not_answered.stderr
  • packages/stack-encrypt/tests/ui/op_matches_on_integer.rs
  • packages/stack-encrypt/tests/ui/op_matches_on_integer.stderr
  • packages/stack-encrypt/tests/ui/op_order_on_bytes.rs
  • packages/stack-encrypt/tests/ui/op_order_on_bytes.stderr
  • packages/stack-encrypt/tests/ui/op_target_does_not_answer.rs
  • packages/stack-encrypt/tests/ui/op_target_does_not_answer.stderr
  • packages/stack-encrypt/tests/ui/op_target_not_labelled.rs
  • packages/stack-encrypt/tests/ui/op_target_not_labelled.stderr
  • packages/stack-encrypt/tests/ui/op_verify_exact_term.rs
  • packages/stack-encrypt/tests/ui/op_verify_exact_term.stderr
  • packages/stack-encrypt/tests/ui/order_term_of_an_8_bit_integer.rs
  • packages/stack-encrypt/tests/ui/order_term_of_an_8_bit_integer.stderr
  • packages/stack-encrypt/tests/ui/owned_fan_out_needs_clone.rs
  • packages/stack-encrypt/tests/ui/owned_fan_out_needs_clone.stderr
  • packages/stack-encrypt/tests/ui/pass/indexes.rs
  • packages/stack-encrypt/tests/ui/pass/owned_without_clone.rs
  • packages/stack-encrypt/tests/ui/pass/plan_chain.rs
  • packages/stack-encrypt/tests/ui/pass/query_only_and_borrowed.rs
  • packages/stack-encrypt/tests/ui/plaintext_needs_encrypt.stderr
  • packages/stack-encrypt/tests/ui/plan_match_on_integer.rs
  • packages/stack-encrypt/tests/ui/plan_match_on_integer.stderr
  • packages/stack-encrypt/tests/ui/plan_query_undeclared_index.rs
  • packages/stack-encrypt/tests/ui/plan_query_undeclared_index.stderr
  • packages/stack-encrypt/tests/ui/struct_field_must_open.rs
  • packages/stack-encrypt/tests/ui/struct_field_must_open.stderr
  • packages/stack-encrypt/tests/value_kinds.rs
  • packages/stack-guest-abi/Cargo.toml
  • packages/stack-guest-abi/src/abi.rs
  • packages/stack-guest-abi/src/buffers.rs
  • packages/stack-guest-abi/src/call.rs
  • packages/stack-guest-abi/src/last_error.rs
  • packages/stack-guest-abi/src/lib.rs
  • packages/stack-guest-abi/src/status.rs
  • packages/stack-guest-abi/src/step.rs
  • packages/stack-guest-abi/src/value.rs
  • scripts/__tests__/bench-index-expressions.test.mjs
  • scripts/__tests__/dependabot-eql-inherited-ignores.test.mjs
  • scripts/__tests__/eql-suite-ci.test.mjs
  • scripts/__tests__/ffi-binding-action.test.mjs
  • scripts/__tests__/lib/rust-compiled-files.mjs
  • scripts/__tests__/rust-compiled-files.test.mjs
  • scripts/__tests__/tests-workflow-gate.test.mjs
  • scripts/__tests__/wasm-build-inputs-paths-filter.test.mjs

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@changeset-bot

changeset-bot Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b104982

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

This PR includes changesets to release 27 packages
Name Type
@cipherstash/protect-ffi Patch
@cipherstash/auth Patch
@cipherstash/eql Minor
stash Patch
@cipherstash/stack-drizzle Patch
@cipherstash/stack-supabase Patch
@cipherstash/stack Patch
@cipherstash/ffi-integration-tests Patch
@cipherstash/wizard Patch
@cipherstash/stack-prisma Patch
@cipherstash/bench Patch
@cipherstash/test-kit Patch
@cipherstash/basic-example Patch
@cipherstash/prisma-example Patch
@cipherstash/e2e Patch
@cipherstash/protect-ffi-darwin-arm64 Patch
@cipherstash/protect-ffi-darwin-x64 Patch
@cipherstash/protect-ffi-linux-arm64-gnu Patch
@cipherstash/protect-ffi-linux-x64-gnu Patch
@cipherstash/protect-ffi-linux-x64-musl Patch
@cipherstash/protect-ffi-win32-x64-msvc Patch
@cipherstash/auth-darwin-arm64 Patch
@cipherstash/auth-darwin-x64 Patch
@cipherstash/auth-linux-arm64-gnu Patch
@cipherstash/auth-linux-x64-gnu Patch
@cipherstash/auth-linux-x64-musl Patch
@cipherstash/auth-win32-x64-msvc 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

@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Mutation testing (cargo-mutants, --in-diff, stack-auth + stack-encrypt)

caught missed unviable timeout
583 0 409 0

cargo-mutants exited with no surviving mutants recorded. The run may not have completed cleanly; check the workflow run logs.

@coderdan
coderdan added this pull request to stack #1230 October 16, 2026 11:24
@coderdan
coderdan removed this pull request from stack #1230 October 17, 2026 05:57
@coderdan
coderdan added this pull request to stack #1247 October 18, 2026 00:13
@coderdan
coderdan removed this pull request from stack #1247 October 18, 2026 05:50
…n the code is generated

gensupport converts a built-in integer to a kind of 64 bits or fewer only,
and intoKind took any integer target, so a field of a 128-bit EQL type
would generate, build, and fail on every Encrypt. No producible EQL type
has a 128-bit kind today; intoKind now refuses one, and lowering names
the field and both kinds.
…sed when it seals too

The breaking note named the open path only. A host that sends a narrow
leaf for a field declared int32 is now refused with FieldType at seal,
where it was widened; Go code generated before still seals, because
gensupport converts to the declared width. ValueFrame::of's errors no
longer name a 128-bit integer and a date as outside the model.
feat(stack-encrypt)!: hold a dynamic plaintext as its frame, not a value tree
feat(stack-encrypt,golang): give every Go integer width, dates, timestamps, decimals and 128-bit integers their own kinds
…rough fields unauthenticated

A passthrough field comes back beside the decrypted ones in one map, but
nothing authenticates it: a writer to the store can change it and decrypt
succeeds. The decrypt docs now say so.
… as OpenedType, not Aead

A typed decrypt collapsed every failure vitaminc reports into Error::Aead,
the error for a wrong key, a wrong context or a tampered ciphertext. That
included a leaf that authenticated and only held another type than the
target reads: an integer opened as String, say. The Go guest then
reported a value sealed as another type as STATUS_AUTH, i.e. tampering.

vitaminc's DecryptError already tells the sink's refusal apart from the
cipher's, so open_keyed now maps DecryptError::Sink to the new
Error::OpenedType, naming only the type the target reads (never the map
key a DecodeError can carry). Every other failure stays Aead. Telling a
wrong-type reader apart reveals nothing, because the sink runs only after
every leaf has authenticated. The guest maps OpenedType to
STATUS_ENCODING, as it already maps a typed record field that opens to
another kind.

Closes #1118.
fix(deps): take chacha20 0.10.2, since 0.10.0 and 0.10.1 were yanked
…m Aead

A container's leaves authenticate one by one, but its membership does
not: a map entry's AAD binds only its key, and a sequence element's binds
no index. So an entry removed or repeated, or elements reordered or
dropped, still authenticate, and the target's refusal of the result
(MissingField, DuplicateKey, or Expected on a reshaped container) can be
tampering. open_keyed now reports OpenedType only when the tree is one
leaf and the target refused its kind. Every other failure, every refusal
of a container's value included, stays Aead.

Found by review on #1256.
…ed-passthrough note

A plan's context field is stored as a passthrough, but a change to it is
caught: every other field was sealed under it, so decrypt fails with
ContextMismatch against the expected context, or the sealed fields do not
open. Found by review on #1255.
…part from Aead", and say why

This reverts commit 8e904f8. A container's membership and order are
deliberately not authenticated: a stored sequence is a set of rows and a
stored map a row's columns, and a database returns rows in any order and
a query selects some columns, not all. Authenticating position or presence
would break exactly those reads. So a target refusing a container's shape
is a shape mismatch, OpenedType, not tampering.

The rationale now sits on open_keyed, on Error::OpenedType and in the
CHANGELOG, and a test opens a Vec<u32> as u32 and expects OpenedType, so a
later review that reads the missing membership check as a defect meets
the reason first.
…cated

docs(stack-encrypt): say that dynamic::record::decrypt returns passthrough fields unauthenticated
…at is not a finding

Agent reviews have flagged, four or five times, that a stored container's
membership and order are not authenticated. That is deliberate (vitaminc
ADR 0002): stored values are rows and columns, read in any order and in
part. stack-encrypt ADR 0010 applies it to what Stack Encrypt stores: each
leaf is bound to its context, key, role, type and version; a container's
membership and order, a passthrough field (except a context field), and
which row a leaf belongs to are not.

AGENTS.md gains "Review guidelines" with these as known non-findings
(Codex reads it; CLAUDE.md imports it for Claude Code's /code-review), and
.github/copilot-instructions.md repeats them for Copilot.
…ild may break

The record fixtures prove that two authors of one record agree today, and
are regenerated when the encoding moves, so a change that breaks rows
already stored can be regenerated away. stored_rows_v1.json is the
opposite: rows the next build stored under the deterministic key source,
written once by an ignored test that refuses when the file exists, and
never regenerated. STACK_ENCRYPT_UPDATE_FIXTURES does not touch it.

Every case must open to the frame it opened to, and sealing its source
again must give the same tree apart from the leaves' nonces: the same
shape and keys, terms and passthroughs. The cases cover every value kind
with every index it admits, the non-default match options, composites
with empty containers, an untyped field, a renamed field, a passthrough,
three-segment labels, one and two extension parts, a context field, and
a batch. A one-byte change to a stored term or leaf fails the test.

Refs #1119.
…ust and Go

v4_rows.json proves the Go SDK and Rust agree today and is regenerated
with EQL_UPDATE_FIXTURES=1, so a change that breaks rows already stored
can be regenerated away. stored_v4_rows_v1.json is a frozen copy of the
Profile rows the Go SDK's generated code stored with the next build: one
value of every producible EQL v4 type but TextEq. Nothing writes it.

Rust opens every frozen value as its v4 type
(frozen_rows_the_go_sdk_stored_still_open). Go seals the frozen
plaintexts again and requires the same envelopes and terms, and opens
every committed ciphertext (TestFrozenV4RowsStillOpen). A one-byte change
to a stored term fails the Go test.

Refs #1119.
…ver every producible type

Profile stored one value of every EQL v4 type the engine produces except
TextEq, so neither v4_rows.json, nor v4_queries.json, nor the frozen
stored_v4_rows_v1.json held a TextEq payload. Profile gains Email
(encrypt_into=TextEq), and every reader follows: the generated code, the
Go tests' row and query helpers, the Rust rows reader, and the Postgres
test's table, insert and = query.

v4_queries.json gains the email query and is otherwise byte-identical.
v4_rows.json is regenerated: the email column is new, and the other
ciphertexts carry fresh nonces. stored_v4_rows_v1.json is not merged yet,
so it is copied again from the new rows before it is frozen.

Refs #1119.
…ot-aead

fix(stack-encrypt)!: report a ciphertext that opens as the wrong type as OpenedType, not Aead
…fiValue

eql-bindings' API takes a ValueFrame since the plaintext moved to frames,
but its tests still built every input as an FfiValue and read every
opened value back into one. That kept FfiValue looking like a plaintext
type eql-bindings depends on, which it no longer is.

The tests now write a Rust value straight into a frame
(ValueFrame::of(-7i32), ValueFrame::of("café")) and compare an opened
frame with the frame of the value expected, byte for byte, which checks
the kind and a float's bit pattern too. A null is the frame of
None::<i32>. The README's dispatch example, a Cargo.toml comment and an
unreleased CHANGELOG line still named FfiValue as the dispatch's plaintext
and now say ValueFrame.

No test changed what it asserts. eql-bindings and its encryption tests
no longer name FfiValue anywhere.

Refs #1252.
In a_value_of_another_kind_is_refused_not_converted each case is already
built as a ValueFrame. Wrapping it in frame() again ran ValueFrame::of over
a frame and wrote the same bytes, which read as if the value were still an
FfiValue. Pass the frame straight to targets::encrypt.

Refs #1252
…c frame

The typed-path paragraph named stack_encrypt::dynamic::ValueFrame to say
which leaf each type seals. A typed-only build does not build Stack
Encrypt's dynamic module, so point at the Go SDK instead, which is the
compatibility the sentence is about. The sentence also read badly.

The interoperability matrix still called the other direction "the value
enum". The tests now build value frames, so say that.

Refs #1252
…, and keep dynamic out of stack-encrypt

eql-bindings' stack-encrypt feature turned on Stack Encrypt's dynamic
layer for every user, although only the by-name dispatch a language
binding needs uses it: encryption::targets and the generated v4::targets
take a ValueFrame and name an EQL type at run time. A Rust program that
encrypts an IntegerEq through encrypt_as compiled the whole dynamic layer
for nothing.

stack-encrypt now gives the typed EQL v4 types alone, with Stack
Encrypt's default features off and no dynamic. A new targets feature turns
on stack-encrypt, Stack Encrypt's dynamic feature, and zeroize and
thiserror, which only the dispatch uses, and compiles the two targets
modules. The Go guest's eql build and the encryption tests enable
targets. test:encryption tests eql-bindings under both feature sets, and
the wasm32 check builds targets, as the guest does. docs.rs documents
targets.

The comment on the encryption::targets declaration is a plain comment: a
doc comment there would resolve the module's own intra-doc links from the
parent scope.

Refs #1252.
Before the targets split, stack-encrypt was the only feature, so clippy
with -D warnings and the wasm32-wasip1 check covered the typed path. After
it, both ran only with targets on, and the typed set was built only by a
host cargo test without -D warnings. A lint that fires only without
targets, or a wasm32 break in the typed path, would have passed CI.

test:encryption now also runs clippy on eql-bindings with
--features stack-encrypt alone, and check:encryption:wasi also checks that
set for wasm32-wasip1. Both are clean.

Refs #1252
The encryption module docs lost their link to `targets` when the module
went behind the feature, because a link to a missing module fails the doc
build. Link it with cfg_attr when the feature is on, as lib.rs does, and
keep the plain text otherwise.

docs.rs builds with targets and the crate has no docsrs cfg, so no feature
badge shows. Say in the targets module docs that it needs the feature.

Refs #1252
test: freeze fixtures of stored rows that no later build may break
The Phase 4 note said a decrypted value is always one sealed in that row.
It is not: the entry's AAD binds the keyset, the column's context, the
data key's tag, the selector and the ordinal, and nothing that names a
row. An entry the database returns together with its own row's header
opens, so `->` can be answered with another row's value at the same
path. That is the cross-row interchangeability ADR 0010 accepts for
every value sealed under one context, so the fix is to the wording.

The note now says what is bound, which substitutions open, and that a
selector check would close the path substitution but not the row one.
The leakage page's "What is authenticated" paragraph said "under this
row's data key"; it now says the key the row's header names and points
at the paragraph below it, which already described the row case.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
The prepared-statement check ran six EXECUTEs and read EXPLAIN EXECUTE
under plan_cache_mode = auto. auto keeps a custom plan whenever it costs
less than the generic one, so for the nested table the cache could go on
showing a custom plan, and a generic plan that fell back to a sequential
scan would fail no test. A pooled driver can reach that generic plan.

After the auto assertion, each statement (containment and the range at
an ordered path, on both tables) is explained again under
force_generic_plan, asserted to carry its operand as $1 (so the plan
read is the generic one) and to use the same index, and the setting is
reset. v4_range.rs does the same for a range domain. Passes on
PostgreSQL 17 (the whole test:encryption:postgres task) and 14 (this
test).

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
A path such as `$.items[2147483648]` fits the u32 the subtree key used
for ordinals, so its position reached the server as the gate
`#2147483648:<selector>`, and `json_tree_children` and
`json_tree_subtree_at` cast that ordinal to `integer`: PostgreSQL raised
22003 where the query should have found nothing.

The bound now lives in one place, `MAX_ORDINAL` (2^31 - 1), and is
applied where the index numbers children: when a document is sealed (an
array or object with more children is refused, so every ordinal and child
count fits `integer`), and when a subtree key is derived (a position past
it is refused with `TermError::JsonTooWide`, whether it becomes a gate or
a position the client chains itself). Refusing at derivation rather than
at `JsonPath::parse` keeps `JsonPath` a plain description of a path, used
also for plaintext selection where any position is meaningful, and keeps
the refusal next to the other index-specific one (`JsonSealedRoot`). No
stored document has a node past the bound, so no answer is lost.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
The trait's docs said what a layout is in the abstract and gave no
example, so a reader could not see why it exists beside `EncryptFrom`.
They now say it in short sentences and lead with a runnable example: a
plan built with `encrypt_with_layout(Json::new(options))` orders `$.age`
and answers an ordering query, while the same target laid out by type
(`encrypt_into::<JsonDocument>()`) uses the defaults and refuses it with
`JsonPathNotOrdered`. The docs also say that the cipher's `encrypt_as` is
a different layer: one value, the type's own layout, no plan.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
…out docs

The module docs were one long sentence naming three layouts, and the
method docs explained `encrypt_with_layout` through the `Layout` trait's
abstractions before saying what a caller gets. The module docs now list
the three ways to choose a one-value plan's output, one line each. The
method docs say what it does and what it returns in two sentences, lead
with the example, and then say when to use it rather than
`encrypt_into::<JsonDocument>()`. The note that the cipher's `encrypt_as`
is a different layer moved to the `Layout` trait, which now explains the
distinction with an example of its own.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
…o serde

`JsonOptions::ordered` holds `JsonPath`s, but the wire structs that write
and read it held `Vec<String>`: the writer rendered each path to text by
hand and the reader re-parsed the strings in a `TryFrom`. The type was
lost one step before the serde boundary rather than at it.

`JsonPath` now implements `Serialize` (its `Display` text) and
`Deserialize` (through `JsonPath::parse`, refusing text that is not a
path with the `JsonPathError` message). The wire structs hold the
`BTreeSet<JsonPath>` itself, so the paths stay typed until serde turns
them into strings, and what the `TryFrom` still checks is only the one
rule a parse cannot: an ordered path must not name a position. The wire
form is unchanged (paths in canonical order, as text), and the plan
error's structured payload writes the set the same way.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
The unreleased JSON index entry now says that `JsonTooWide` also refuses
a subtree key for a path naming a position past 2^31 - 1, which the SQL
walk casts to `integer`.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
… field

The json_tree wire types held a bare `String`, so a field's type did not
say how its text was to be read, and `h` reused the v3 SteVec
`KeyHeader`, whose docs describe base85 text the database never parses,
where the v4 header is base64 that the SQL decodes for the `iv` and the
sealed-root flag.

The new `encoding` module has two `#[serde(transparent)]` newtypes,
`Base64Text` (padded standard base64, as `encode(x, 'base64')` writes it)
and `Base85Text` (RFC 1924 base85, which no SQL function decodes). The
selector, parent tag and ordering term wrap `Base64Text`, the ciphertext
wraps `Base85Text`, and `h` is a new `JsonTreeKeyHeader(Base64Text)`. The
wire form does not change: each newtype is the bare string in JSON, and
`string` in TypeScript and JSON Schema. Deserializing still checks only
that the value is a string; Stack Encrypt decodes the bytes and refuses
text that is not its encoding. The json_tree family is not in the
catalog, so no generated TypeScript, JSON Schema or Go output moves.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
`json_tree_subtree_at` limited its walk only when the root was sealed and
the budget was above zero, and `json_tree_children` not at all, so with
`budget = 0` or an open root nothing in the SQL itself said how many rows
a walk of a hostile stored document could make. The bound held, but only
as a consequence of two facts elsewhere: the parent map keeps one entry
per tag, so entries that share a `p` collapse into one, and a hit's token
is a hash of the probe that found it, so no probe is made twice.

Both walks now read their recursion through `LIMIT` the entry count plus
the seed row, as #1325 had them before the ordinal chain replaced the
stored tokens. PostgreSQL computes a recursive query only as far as its
reader pulls rows, so the limit stops the recursion and not only the
output, and a walk of a sealed document never reaches it. The budget's
fallback is unchanged: `found` reads the bounded walk, so a document with
fewer entries than the budget is returned walked, and one with more falls
back past the budget as before. The comment block above the walks now
states the bound and both reasons for it.

The Postgres suite gains a hostile document whose 60 levels are each
written twice, same `p` and `s`, different `c`. Walked once per copy it
would make 2^60 rows; it returns one row per level under no budget, an
open root, and a budget above the entry count, and falls back under a
budget below it. It passes with and without the new limit, which is the
evidence that the map already collapsed the copies.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
The ordinal-chain changeset's byte-encodings paragraph now says that the
eql-bindings wire types name their encoding (`Base64Text`, and
`Base85Text` for `c`) and that the wire form is unchanged.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
…, not copy them

When a walk falls back to the sealed root, the client opens the whole
document and selects the walked path from it. The selection borrowed the
document and cloned the node (or the nodes, or a node's children) out,
so for a moment the selected plaintext existed twice: once in the
document, which was then wiped, and once in the copy handed over.

`JsonPath::select_mut` finds the same nodes as `select`, borrowed
mutably, and the new `plain::take_protected` is the moving counterpart
of `read_protected`: it borrows the `Protected` inner value through
vitaminc's `update`, moves out what the closure returns into a
`Protected` of its own, and leaves the source wrapped. Both fallbacks
(`DecryptInto<Value>` and `DecryptInto<Vec<Value>>` for `JsonSubtree`)
now `mem::take` the selected nodes, leaving `null` in the document, and
the children of a `json_tree_subtree` fallback are taken the same way,
an object's keys staying behind to be wiped with the document. No
`risky_unwrap` was added, and the plaintext exists once.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
…nal tokens and the header

Two review findings on the record (#1250) read the design as written and
found two gaps that the implementation closed in #1329, with nothing in
the record saying so. A positional token as first written named the
element's children rather than the element, so a scalar element could not
be returned or identified; the implementation reaches a position from the
parent's token through a `#n:<selector>` gate and returns the reached entry
itself. The wire shape called the header opaque to SQL while the walk
needs the document's iv and the sealed-root flag from it; the
implementation reads both at fixed offsets of the frozen header layout.
Each passage now carries a dated note pointing at the implementation and
the phase notes, in the form the record already uses for superseded
sections.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
…pt-spike

docs(plans): a JSON index for Stack Encrypt as a new EQL v4 domain, with runnable SQL prototypes
next moved 106 commits past this branch's base while #1250 was open. Conflicts resolved:

- dynamic: next's order terms on decimal, date and timestamp removed Reason::OrderTermPending; the JSON index's Reason::JsonIndexPending stays, and IndexSpec::Json keeps its arms beside next's typed order_of.
- stack-encrypt Cargo.toml: next's serdect beside this branch's base64 comment.
- eql-bindings v4 docs: next's order-term paragraph with the json_tree paragraph.
- stack-encrypt CHANGELOG: both sides' entries.
- Lockfiles: next's, plus the one sha2 edge this branch adds to stack-encrypt.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
…-ordinal-chain

Lockfile conflicts only: the base branch's locks, which now carry next, plus this branch's base85-simd 0.1.0, the version it already pinned.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
…oding

The encoding newtypes exposed their inner String, so anyone could put any
text inside one, and a consumer holding a Base64Text could not rely on it
being base64. A type that names an encoding is only worth having if holding
one means the text is in it.

The inner string is now private, and there are two ways to make a value.
`encode` takes bytes and writes the text itself. `Deserialize`, the way
every wire value arrives, decodes the text with the real decoder and fails
with an error naming the encoding when it is not padded standard base64 or
RFC 1924 base85. Base85 text whose final group decodes but is not the one
`encode` writes for those bytes is refused too, so text and bytes determine
each other and equality on the text is equality on the bytes. `decode` is
therefore infallible. `as_str`, `AsRef<str>` and `Display` give the text;
the wire form is still the bare string, and TypeScript and JSON Schema
still render a string.

The cost is a decode per field on read: once here and once more in Stack
Encrypt for the fields it uses.

The module now needs the encoders, so it moves under the `stack-encrypt`
feature with the json_tree types that are its only users, and eql-bindings
gains base85-simd 0.1.0, the version Stack Encrypt uses (the EQL and Go
guest lockfiles record the new edge; neither gains a crate). proptest
becomes a dev-dependency for the round-trip properties. The json_tree unit
tests built entries from placeholder strings that are not in either
encoding; they now build them with `encode`, and one more test pins that a
field in the wrong encoding fails the entry.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
…crypt gated ones

`encoding` now sits behind the `stack-encrypt` feature with the json_tree
types that use it, so protect-ffi, which builds eql-bindings with no
features, no longer compiles it. The compiled-file walk drops it, and the
check that the walk drops only the feature-gated modules named `v4` and
`encryption` alone, so it failed on the file it was meant to allow. It now
names `encoding` too, as do the two comments describing which modules the
binding leaves out.

Gating the module is also what clears the earlier failure on this branch:
while `encoding` was compiled into the binding, the binding's cache keys did
not name it.

Claude-Session: https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu
feat(stack-encrypt, eql): the JSON index and the json_tree EQL v4 domain family
…jection

perf(eql, stack-encrypt): store the json_tree projection, walk by parent map, budget the subtree
feat(eql, stack-encrypt): chain json_tree tokens by ordinal and probe the walk to the first miss
test(eql): hold the planner to the json_tree indexes on every supported PostgreSQL, and document what the tree reveals

This branch was successfully deployed

1 active (outdated) deployment
release-golang — a05affaa Deployed Oct 19, 2026 by coderdan via Tag and release #3
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