Repository navigation
Conversation
🦋 Changeset detectedLatest commit: a629897 The changes in this PR will be included in the next version bump. This PR includes changesets to release 12 packages
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 |
|
Warning Review limit reachedOnly developers with an assigned seat can use this organization's usage-based review budget, and seats here are assigned manually. Ask an admin to assign a seat, or change the review continuation mode in Billing. Next included review available in 12 minutes. View limit details
Comment |
Mutation testing (cargo-mutants,
|
90341fc to
c14138f
Compare
coderdan
left a comment
There was a problem hiding this comment.
Review of this PR's own changes (feat/eql-v4-bundle...feat/eql-v4-bindings). The codegen and the trait move hold up: the generated v4 domain names match what the {{prefix}} SQL renders, and moving the derives off v3 breaks no released crate. crates.io eql-bindings 0.1.0 through 3.0.6 publishes no features, and protect-ffi does not enable stack-encrypt. One release-coherence problem, two gaps in the gates and tests, and two small doc issues.
What I ran on the head commit (c0f074f): cargo test for eql-codegen, for eql-bindings --all-features and for eql-encryption-tests (all pass); clippy -D warnings and cargo fmt --check on those crates (clean); cargo publish -p eql-bindings --dry-run --all-features (builds against registry stack-encrypt 0.2.0); and cargo check --locked in protect-ffi's workspace (passes).
1. Major: the next EQL release would publish a v4 producer with no v4 SQL to install it into
Where: .changeset/eql-v4-bindings.md:2, packages/eql/crates/eql-bindings/src/sql.rs:7, .github/workflows/_build-eql-sql.yml:95-96, packages/eql/crates/eql-bindings/src/v4/mod.rs:15
Problem: This PR turns the stack-encrypt feature into a producer of "v": 4 payloads, and they only pass the public.eql_v4_* domain checks. The two pending changesets already release that feature, and the new changeset makes it a minor bump. Through the lockstep version sync, the next release publishes eql-bindings 3.1.0 with this behaviour. No released artefact carries the v4 SQL:
eql_bindings::sql::INSTALL_SQL/UNINSTALL_SQLembed onlysql/cipherstash-encrypt*.sql, which is v3._build-eql-sql.ymluploads onlycipherstash-encrypt.sqlandcipherstash-encrypt-uninstall.sql.@cipherstash/eql/sqlandstash eql installinstall only v3.
None of #1161 or #1163–#1166 touches those paths. So a crates.io user who enables stack-encrypt gets payloads that every released install rejects at INSERT, while the published README tells them to use public.eql_v4_text_eq.
Why it matters: The release would also contradict its own plan. ADR-0002 (docs/adr/0002-…md:226) says "@cipherstash/eql 4.x ships both bundles", and v4/mod.rs:15 says the rest follows in 4.0. This change would ship the v4 types in a 3.x minor instead.
Suggested fix: Pick one and write it down in the PR:
- (a) Ship the v4 bundle in the same release: a
sql::INSTALL_SQL_V4/UNINSTALL_SQL_V4, the v4 files in the crate'ssql/and the release manifest, and the release upload. - (b) Keep these changesets from releasing until the bundle ships, for example by holding the stack or marking the
stack-encryptsurface unstable.
If (b), say so in the changesets so the Version Packages PR does not pick them up by accident.
2. Minor: types:check, types:generate and the pre-commit hook do not cover src/v4
Where: packages/eql/mise.toml:359, :396, :401; packages/eql/tasks/githooks/pre-commit:18
Problem: eql-codegen bindings now writes crates/eql-bindings/src/v4/*, but these three places still name only src/v3:
types:checkrunsgit diff --exit-codeandgit ls-files --othersonsrc/v3only. It regenerates v4 in place and then passes even when the committed v4 files were stale.types:generatesnapshots and restores onlysrc/v3, so if the run fails, v4 is left rewritten. The task's "atomic on failure" comment no longer holds.- The pre-commit hook regex has no
crates/eql-bindings/src/v4/, so a commit that edits only a generated v4 file runs no gate.
CI still catches v4 drift, through bindings_parity.rs under test:crates (cargo test -p eql-codegen). But types:check is the gate AGENTS.md documents, and it now reports fresh on a stale tree. #1163–#1166 do not change this.
Suggested fix: Add crates/eql-bindings/src/v4 to the diff and untracked lists, to the snapshot/restore trap, and to the hook regex.
3. Minor: no test checks the version boundary that the change relies on
Where: packages/eql/crates/eql-bindings/src/v4/mod.rs:84-99, packages/eql/tests/encryption/tests/targets.rs:271
Problem: The new changeset and the module docs say v4's SchemaVersion "rejects any other version, so a v3 payload fails at the type boundary instead of at INSERT". Nothing tests that:
- No test deserializes a well-formed
"v": 3TextEq, withcand a 64-hexhm, intov4::text::TextEqand expects a refusal. None tests the reverse (v: 4intov3) either. - The one
v: 3input in the stack-encrypt path,refuses_bytes_that_are_not_the_type, is{"v":3,…,"hm":"00"}. It is refused becausecis missing, not because of the version, so it would still pass if v4'sSchemaVersionaccepted 3. This matters most for decrypt, because earlier builds of this tree wrote Stack Encrypt payloads withv: 3and the samestack-encrypt:1:prefix. - v4 also has no counterpart to v3's
catalog_parity.rs, which would pin each v4 inventory entry'ssql_domain, its query twin's schema (eql_v4.),schema_idunder/eql/v4/and its term keys.
Suggested fix:
- Add a well-formed
v: 3stored payload torefuses_bytes_that_are_not_the_type. - Add a unit test in
eql-bindingsthatv4::text::TextEqrefusesv: 3andv3::text::TextEqrefusesv: 4. - Add a small v4 parity test that walks
v4::all()andv4::all_query().
4. Nit: broken intra-doc link without the feature
Where: packages/eql/crates/eql-bindings/src/v4/mod.rs:12
Problem: [targets] points to a module that exists only under #[cfg(feature = "stack-encrypt")]. Running cargo doc -p eql-bindings with default features gives a new warning: "unresolved link to targets". docs.rs builds with the feature, so the published docs are fine. A future -D warnings doc gate would fail on it.
Suggested fix: Write it as plain code text, or as [targets](crate::encryption::targets) behind the feature.
5. Nit: the Go READMEs describe a setup that now fails on insert
Where: languages/golang/encrypt/README.md:276, :281; languages/golang/cmd/stashgen/README.md:47
Problem: These still tell users to store eql.TextEq in a public.eql_v3_text_eq column and query through eql_v3.query_text_eq. After this PR the guest writes "v": 4, which the v3 domain check rejects. #1165 fixes both files, so this only matters if the stack does not merge together. If it might not, move those README edits into this PR.
c0f074f to
24b9228
Compare
|
Rebased onto the updated #1161, then pushed 24b9228, which answers items 2–5 of the review above. Item 1 is still open and needs your decision (see the end).
Item 1, the release with no v4 SQL to install into, is a decision I've left for you.
I'd lean (b) for now. The Go alpha gets its v4 SQL from the Go release (#1166/#1167), not from npm or crates.io. Also on this restack: #1163 gained a commit that fixes two |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
tobyhede
left a comment
There was a problem hiding this comment.
Review attestation: files reviewed - the 3 PR commits (487b5b6, ef1878b, 24b9228): eql-codegen bindings/targets, eql-bindings v3/v4 modules, encryption/targets.rs, encryption tests, mise.toml, Go encrypt/eql, stack-encrypt fixtures, changesets, AGENTS.md. Models: Claude Sonnet 5.5 (claude-sonnet-5-5), single pass, no verifier.
Generated by Claude Code
| '@cipherstash/eql': minor | ||
| --- | ||
|
|
||
| **The `eql-bindings` crate has an `eql_bindings::v4` module: payload types for the EQL v4 domains.** EQL v4 is the v3 SQL installed under a second name (ADR-0002), for values written by Stack Encrypt. The module is generated from the same catalog as `v3`, with `eql_v4_*` domain names and `"v": 4`, and has its own `SchemaVersion`, which rejects any other version. Only v4 types derive Stack Encrypt's `EncryptFrom` and `DecryptInto`, and the Stack Encrypt target table names v4 domains. The `v3` types and the TypeScript package are unchanged. |
There was a problem hiding this comment.
The changeset says "The v3 types ... are unchanged", but this PR removes public API from v3: eql_bindings::v3::targets (the whole module moved to v4) and the EncryptFrom/DecryptInto impls on v3::text::TextEq and TextEqQuery. Any consumer using the stack-encrypt feature with v3 types stops compiling. If no release carried the feature, say so here and say these were removed. If one did, this needs a breaking bump rather than minor.
Generated by Claude Code
| /// ciphertext prefix. A real, well-formed v4 payload with only its version | ||
| /// changed is refused, so the version alone is what refuses it. | ||
| #[tokio::test] | ||
| async fn refuses_a_stored_payload_of_the_other_version() { |
There was a problem hiding this comment.
This test pins the new behaviour: a stored Stack Encrypt payload with "v": 3 is refused on decrypt. Its doc comment says earlier builds wrote exactly that. Any data written by the pre-change Go guest or v3::TextEq path becomes undecryptable, and nothing offers a re-version or migration path. If that data is known not to exist outside tests, record it in the changeset. If it might exist, decrypt needs a read-only compatibility path for v: 3 payloads with the stack-encrypt:1: prefix.
Generated by Claude Code
| /// boundary instead of at INSERT. The inner value is private; the only | ||
| /// constructible instance is `4`. | ||
| #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, TS)] | ||
| pub struct SchemaVersion(#[ts(type = "4")] u16); |
There was a problem hiding this comment.
SchemaVersion is a near copy-paste of the v3 type in lib.rs: the struct, Deserialize, manual JsonSchema and Default differ only in the constant 3 vs 4 and the schema name. The two will drift, for example if the error message or schema description is edited in one. A single SchemaVersion<const V: u16>, or a macro, would remove the duplication.
Generated by Claude Code
| /// A v4 struct's `DomainType::schema_id` overrides: the trait's defaults name | ||
| /// the v3 schema base. Both forms, since the inventory's `PhantomData` handles | ||
| /// reach the type-level one. | ||
| fn schema_id_override(version: EqlVersion) -> TokenStream { |
There was a problem hiding this comment.
The v4 override emits two near-identical fns (schema_id_base_static and schema_id) into every generated impl, which is about 150 impls. The cause is that DomainType::schema_id defaults to the v3 base. Adding an object-safe schema_id_base(&self) to the trait, defaulting to v3, and having the default schema_id use it would mean v4 types override one method. It would also avoid the "boxed PhantomData fell back to v3" bug this commit had to fix with a second override.
Generated by Claude Code
| // compiled type behind it. | ||
| for row in targets::targets() | ||
| .iter() | ||
| .filter(|r| r.family != "json" || r.suffix.is_empty()) |
There was a problem hiding this comment.
The filter r.family != "json" || r.suffix.is_empty() skips every json-family row that has a suffix, not only the SteVec document. A future json row such as a generated v4 JsonSearch would be silently exempt from the "is a compiled domain type" check. Filter on the SteVec shape or the exact row name instead. Also, TARGETS now advertises public.eql_v4_json* SteVec rows (and eql_v4.query_json) that have no Rust type in v4, and the Go eql_gen.go names them. Check that the Go side cannot select a target the Rust side cannot back.
Generated by Claude Code
|
|
||
| Adding a scalar encrypted-domain type is one row in the Rust catalog `eql-domains::CATALOG` (`crates/eql-domains/src/lib.rs`): a `DomainFamily` giving the type `name` (e.g. `bigint`), its `ScalarKind` (the `kind` field), the `Domain`s mapping each generated (bare) domain name to its fixed index `Term`s (`eq => [Hm]`, `ord`/`ord_ore => [Ore]`), and the `Fixture` value list. Term capabilities are fixed in the `Term` enum's `impl` methods (with unit tests): `Hm` provides equality, and `Ore` provides equality plus ordering. There is no TOML manifest and no Python — the catalog is the source of truth, validated by the compiler (an undefined term or unknown scalar is a compile error) plus catalog `#[test]`s. `mise run build` runs `cargo run -p eql-codegen`, which regenerates the scalar SQL surface into `src/v3/scalars/<T>/` from `CATALOG` at the start of every build; that surface includes supported comparison wrappers plus blockers for native `json` operators that would otherwise be reachable through domain fallback. `cargo run -p eql-codegen` regenerates every type at once (the same call `mise run build` uses; there is no per-type codegen task). The generated `*_types.sql` / `*_functions.sql` / `*_operators.sql` / `*_aggregates.sql` files are **committed in place** under `src/v3/scalars/<T>/` and drift-gated by `mise run codegen:parity` (regenerate in place + `git diff` + untracked check — the same regenerate-and-diff pattern `types:check` uses for the committed bindings). They are still machine-generated: change the catalog and rebuild, never hand-edit (CI fails on drift). The per-type plaintext fixture lists the SQLx matrix consumes are **not** a generated file — they are materialised from each `CATALOG` row at compile time as `eql_domains::INT4_VALUES` / `INT2_VALUES` (the `int_values!` macro) and read directly by `ScalarType::FIXTURE_VALUES`; a Rust source of truth no longer round-trips through a committed generated `.rs`. Generated SQL carries a `-- AUTOMATICALLY GENERATED FILE` header (the project-wide marker `docs:validate` greps on); change the catalog and rebuild, never hand-edit. Hand-written SQL beyond the fixed surface goes in `src/v3/scalars/<T>/<T>_extensions.sql` with no auto-generated header and explicit `-- REQUIRE:` edges — that file IS committed. `json`'s **SteVec** domains never enter this pipeline, but its **scalar storage domain does**: `generate_all` iterates `eql_domains::families_with_scalar_domains()` and renders each family's scalar domains (so `public.eql_v3_json` is generated into `src/v3/scalars/json/`), while `list-types` and the SQLx matrix still iterate `eql_domains::scalar_families()`, which excludes the whole non-scalar `json` family — so `json` stays out of the operator/coverage matrix by construction (a storage-only domain carries no operator matrix), even though its ciphertext-only storage domain now has a generated SQL surface. | ||
|
|
||
| **EQL v4 bindings:** the generator writes the scalar domains a second time into `crates/eql-bindings/src/v4/` (`eql_v4_*` names, `v: 4`, its own `SchemaVersion`, an `inventory.rs`), plus the Stack Encrypt target table `v4/targets.rs`. **Only v4 structs derive Stack Encrypt's `EncryptFrom`/`DecryptInto`**: Stack Encrypt's output is not byte-for-byte compatible with cipherstash-client's, so `encryption_gap` refuses every v3 domain and a codegen test asserts no v3 struct derives either. v4 has no SteVec bindings, payload enums, TypeScript export or published JSON Schema yet. The hand-written `v4/mod.rs` re-exports v3's term newtypes and `DomainType`. |
There was a problem hiding this comment.
This new paragraph adds v4, but the unchanged text below it still describes types:check as diffing "all three (crates/eql-bindings/src/v3 + bindings/ + schema/)". types:check and types:generate now also cover src/v4, and the pre-commit hook triggers on it. The stale sentence is exactly the drift the repo's meta-file rule warns about, so update it in this PR.
Generated by Claude Code
| pub mod text; | ||
| pub mod timestamp; | ||
|
|
||
| pub use crate::SchemaVersion; |
There was a problem hiding this comment.
pub use crate::SchemaVersion is now v3::SchemaVersion while v4 defines a different type with the same name, and eql_bindings::SchemaVersion at the crate root is still the v3 one. A consumer who writes use eql_bindings::SchemaVersion with a v4 struct gets a type mismatch that looks like the wrong crate version. Consider renaming the root one SchemaVersionV3 (keeping an alias) or documenting at the root that it is v3-only.
Generated by Claude Code
cipherstash-agent
left a comment
There was a problem hiding this comment.
Automated review attestation
Reviewed head 24b9228 with Claude Code /code-review medium, then cross-checked each finding against the diff.
🔴 Blocking
- The changeset misstates the v3 impact.
.changeset/eql-v4-bindings.mdsays the v3 types are "unchanged", but v3 loses itsEncryptFrom/DecryptIntoderives and the publiceql_bindings::v3::targetsmodule. That is a breaking change shipped asminor. The existing changesets were also edited in place, so the v3 → v4 change is in no CHANGELOG (inline comment).
🟠 Should fix
- No migration guidance for stored
"v": 3Stack Encrypt payloads, which are now rejected (inline comment ontargets.rs). - The Go README gives no v4 install step, and no
skills/file was touched. Checkstash-cliandstash-indexing(inline comment).
🟡 Nits
- Stale comment in
eql-codegen/src/targets.rs(~L148). It still nameseql_v3.query_json. The json SteVec rows nameSteVecQuery/eql_v4.query_json, which have no v4 compiled type, and the parity test special-cases this. - Shared term types. v4 shares v3's term types (inline comment on
v4/mod.rs).
Generated by Claude Code
| '@cipherstash/eql': minor | ||
| --- | ||
|
|
||
| **The `eql-bindings` crate has an `eql_bindings::v4` module: payload types for the EQL v4 domains.** EQL v4 is the v3 SQL installed under a second name (ADR-0002), for values written by Stack Encrypt. The module is generated from the same catalog as `v3`, with `eql_v4_*` domain names and `"v": 4`, and has its own `SchemaVersion`, which rejects any other version. Only v4 types derive Stack Encrypt's `EncryptFrom` and `DecryptInto`, and the Stack Encrypt target table names v4 domains. The `v3` types and the TypeScript package are unchanged. |
There was a problem hiding this comment.
🔴 Blocking: the changeset says "The v3 types … are unchanged", but this PR removes public v3 API.
Verified in the diff:
v3::text::*lose theEncryptFrom/DecryptIntoderives.- The public
eql_bindings::v3::targetsmodule is removed. It is nowv4::targets.
A downstream crate using keyset.encrypt_as::<v3::...> or v3::targets::* with the stack-encrypt feature stops compiling on a minor bump. Either keep the v3 derives and module for one release, or ship this as a documented breaking change. In both cases the changeset text must say what was removed.
Also, the PR edits eql-plan-field-targets.md and eql-text-equality-transcoding.md in place. If those already shipped, the v3 → v4 change for existing Stack Encrypt and Go users appears in no CHANGELOG. This changeset should carry it.
Generated by Claude Code
| } | ||
| } | ||
|
|
||
| /// Earlier builds wrote Stack Encrypt payloads with `"v": 3` and the same |
There was a problem hiding this comment.
🟠 No migration path for stored "v": 3 Stack Encrypt payloads. This comment records that earlier builds wrote "v": 3 payloads. After this change SchemaVersion rejects them, so targets::decrypt and Go DecryptContact error on every row written by a prior release. Columns typed eql_v3_* also won't accept the new v:4 values. No re-encrypt or backfill guidance appears in the changeset or READMEs. If no such data exists in the wild, say so in the changeset.
Generated by Claude Code
| A field tagged `encrypt_into=TextEq` is stored as one EQL value, the JSON | ||
| PostgreSQL holds in a `public.eql_v3_text_eq` column, as an `eql.TextEq` | ||
| from package `encrypt/eql`. The guest builds the value: the generated code | ||
| PostgreSQL holds in a `public.eql_v4_text_eq` column, as an `eql.TextEq` |
There was a problem hiding this comment.
🟠 The README now says Stack Encrypt writes public.eql_v4_*, but gives no install step. A Go user with only stash eql install (v3) gets type "public.eql_v4_text_eq" does not exist. Name the v4 bundle and how to install it.
Per AGENTS.md, skills/stash-cli and skills/stash-indexing ship to customers. This PR touches no skills/ file. Check whether they need eql_v4 guidance (or confirm the v4 bundle PR below covers it).
Generated by Claude Code
| pub mod text; | ||
| pub mod timestamp; | ||
|
|
||
| pub use crate::v3::domain_type::{DomainType, SQL_SCHEMA}; |
There was a problem hiding this comment.
🟡 Nit (non-blocking): v4 re-exports v3's terms and SQL_SCHEMA, so v4 Ciphertext / Hmac256 are the same types as v3's. The version boundary lives only in the envelope's SchemaVersion. A later v3-only change to terms.rs validation silently changes v4 behaviour. The module doc says the two outputs aren't byte-compatible, yet they share term types. Consider a note, or v4-owned terms.
Generated by Claude Code
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 24b92287d9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| encoded as hex. Serde handles the final EQL JSON envelope only. SQL consumes | ||
| these payloads through the existing `public.eql_v3_text_eq` and | ||
| `eql_v3.query_text_eq` domains and their equality extractor index. Writers and | ||
| these payloads through the `public.eql_v4_text_eq` and | ||
| `eql_v4.query_text_eq` domains and their equality extractor index. Writers and |
There was a problem hiding this comment.
Ship the v4 SQL bundle with the v4 bindings
Released consumers cannot install the domains required by this new API: tasks/release/prepare-bindings-assets.sh:36-58 still copies only the v3 cipherstash-encrypt.sql into the crate/npm packages, and .github/workflows/_build-eql-sql.yml:94-96 uploads only those v3 artifacts. Consequently, code using v4::text::TextEq produces payloads for public.eql_v4_text_eq, but neither the published crate's eql_bindings::sql nor the GitHub release provides the installer that creates that domain; include the v4 installer/uninstaller in the release assets before exposing these bindings.
AGENTS.md reference: packages/eql/AGENTS.md:L254-L254
Useful? React with 👍 / 👎.
… traits on v4 only Stack Encrypt's output is not byte-for-byte compatible with cipherstash-client's, which writes the eql_v3 domains, so an eql_v3 struct deriving EncryptFrom or DecryptInto claims a compatibility that does not exist. ADR-0002 gives Stack Encrypt its own name, eql_v4. eql-codegen now writes the scalar domains a second time into eql_bindings::v4: eql_v4_* names, a SchemaVersion pinned to 4, a schema id under eql/v4, and an inventory. encryption_gap refuses every v3 domain, so TextEq and TextEqQuery derive their traits only in v4, and a codegen test asserts no v3 struct derives either. The Stack Encrypt target table moves to v4/targets.rs and names eql_v4 domains; the Go package encrypt/eql is regenerated from it. v4 has no SteVec bindings, payload enums, TypeScript export or JSON Schema yet. No published eql-bindings carried the stack-encrypt feature, so nothing released loses a trait. The encryption test crate's PostgreSQL test now installs the v4 bundle; the Go guest and the stack-encrypt fixtures name the v4 domains. Refs #1142
The guest's eql-feature round-trip test still asserted "v": 3 after Stack Encrypt moved to writing EQL v4, failing the WASI/Go CI job. Also update two comments that named the v3 envelope and the eql_v3.query_<name> operand.
…he version boundary The inventory boxes PhantomData<T> handles, and their DomainType impl did not forward schema_id, so every v4 entry reported an /eql/v3/ $id. A type-level schema_id_base_static() now carries each type's base through the handle, and the generated v4 types override it. That surfaced in a new v4 parity test, the counterpart of catalog_parity.rs: v4::all() is the scalar catalog under eql_v4 names in catalog order, each query twin lives in eql_v4, term keys match the catalog, and each generation's TextEq refuses the other's version, both directly and through the inventory. The encryption suite refuses a real v4 payload whose version alone was set back to 3. types:generate snapshots and restores src/v4 as well as src/v3, types:check diffs it, and the pre-commit hook triggers on it. The v4 module doc no longer links a feature-gated module, and the Go READMEs name the eql_v4 column and query operand the guest now writes.
24b9228 to
a629897
Compare
Summary
EQL (Encrypt Query Language) is the SQL we install into PostgreSQL so it can search encrypted values. Under ADR-0002 (#1139) the same SQL is installed twice:
eql_v3for values written by cipherstash-client (the TypeScript SDK's engine) andeql_v4for values written by Stack Encrypt (the engine the Go SDK runs). Stack Encrypt's output is not byte-for-byte compatible with cipherstash-client's, so a v3 type that claims to be producible by Stack Encrypt is wrong. This PR generates Rust payload types for v4 and moves all Stack Encrypt support onto them. The SQL and the TypeScript package do not change.Changes
eql_bindings::v4(eql_v4_*names, aSchemaVersionpinned to 4, a v4 schema id, an inventory).encryption_gaprefuses every v3 domain, so only v4 structs deriveEncryptFrom/DecryptInto. A test asserts no v3 struct derives either.v3/targets.rstov4/targets.rsand nameseql_v4domains. Go'sencrypt/eql/eql_gen.gois regenerated from it.TextEqfixture now carries"v":4, with the same equality term.eql-bindingsREADME andpackages/eql/AGENTS.mddescribe the v4 module. The pending@cipherstash/eqlchangesets are updated, and one is added for the v4 module.Verification
cargo testfor eql-codegen, eql-bindings and the encryption test crate passes, plustypes:check,typescript:check,codegen:parityandtest:crates.eql_v4install: store,=/<>, index use, decrypt.mise run go:test,go:lint) with rebuilt guests. stack-encrypt's 541 tests pass. protect-ffi compiles.eql-bindings(3.0.3–3.0.6) has nostack-encryptfeature, so moving the derives breaks nothing released.Related
Refs #1142, #1145. Stacked on #1161.
https://claude.ai/code/session_01CA4pFfaN4DPNSTLnJVNxsu