Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
402 commits
Select commit Hold shift + click to select a range
a5d4d66
fix(stashgen): refuse a built-in integer stored as a 128-bit kind whe…
coderdan Oct 18, 2026
4b039db
docs(stack-encrypt): an 8- or 16-bit leaf under a 32-bit type is refu…
coderdan Oct 18, 2026
c9b6d77
Merge pull request #1245 from cipherstash/feat/stack-encrypt-frame-sinks
coderdan Oct 18, 2026
6197e29
Merge pull request #1246 from cipherstash/feat/golang-value-kinds-v2
coderdan Oct 18, 2026
95c6ae6
docs(stack-encrypt): say that dynamic::record::decrypt returns passth…
coderdan Oct 18, 2026
bd0fe7b
fix(stack-encrypt)!: report a ciphertext that opens as the wrong type…
coderdan Oct 18, 2026
3cba0f6
Merge pull request #1248 from cipherstash/fix/chacha20-0.10.2
coderdan Oct 18, 2026
8e904f8
fix(stack-encrypt): tell only a single leaf of another kind apart fro…
coderdan Oct 18, 2026
969b38c
docs(stack-encrypt): carve the context field out of the unauthenticat…
coderdan Oct 18, 2026
07fa826
Revert "fix(stack-encrypt): tell only a single leaf of another kind a…
coderdan Oct 18, 2026
0c90e0d
Merge pull request #1255 from cipherstash/docs/passthrough-unauthenti…
coderdan Oct 18, 2026
7ab2614
docs: record what a stored value authenticates, and tell reviewers wh…
coderdan Oct 18, 2026
7ca7ba3
test(stack-encrypt): freeze a fixture of stored rows that no later bu…
coderdan Oct 18, 2026
bb62c86
test(eql,golang): freeze the EQL v4 rows the Go SDK stores, read by R…
coderdan Oct 18, 2026
9d5768e
test(golang,eql): store a TextEq field in Profile, so the fixtures co…
coderdan Oct 18, 2026
777f297
Merge pull request #1256 from cipherstash/fix/decrypt-type-mismatch-n…
coderdan Oct 18, 2026
36aadd6
test(eql-bindings): build test values as frames of Rust values, not F…
coderdan Oct 18, 2026
458d37a
test(eql-bindings): pass the refused-kind frames as they are
coderdan Oct 18, 2026
75336d3
docs(eql-bindings): describe the typed leaf without naming the dynami…
coderdan Oct 18, 2026
102a2f4
feat(eql-bindings): put the by-name dispatch behind a targets feature…
coderdan Oct 18, 2026
52e6fd2
ci(eql-bindings): lint and wasm-check the stack-encrypt set on its own
coderdan Oct 18, 2026
e43dfaf
docs(eql-bindings): say the by-name dispatch needs the targets feature
coderdan Oct 18, 2026
beeaef0
Merge pull request #1257 from cipherstash/test/stored-rows-fixture
coderdan Oct 18, 2026
d9bd121
Merge pull request #1259 from cipherstash/test/eql-bindings-no-ffivalue
coderdan Oct 18, 2026
3167e75
Merge pull request #1260 from cipherstash/feat/eql-bindings-targets-f…
coderdan Oct 18, 2026
cd6d7c5
fix(eql): build the TextEq query fixture's input as a frame, so v4_ty…
coderdan Oct 18, 2026
c612ed4
Merge pull request #1261 from cipherstash/fix/next-v4-types-texteq-frame
coderdan Oct 18, 2026
e0cfdd9
feat(eql): give EQL v4 range query domains and eql_v4.between
coderdan Oct 17, 2026
319a954
docs(eql): say a range must be cast to its exact domain, and what its…
coderdan Oct 17, 2026
9ef1e17
test(eql): smoke-test between over every ordered family, and pin the …
coderdan Oct 17, 2026
b7a793c
build(eql): validate the v4-only range files in docs:validate:documen…
coderdan Oct 17, 2026
d5184c2
feat(eql-bindings): produce Smallint and SmallintEq from i16
coderdan Oct 18, 2026
337e882
test(golang,eql): seal the smallint EQL v4 types from Go, and store G…
coderdan Oct 18, 2026
5887218
Merge pull request #1267 from cipherstash/feat/eql-v4-smallint
coderdan Oct 19, 2026
b5baedb
build: take vitaminc 0.6.1, which reads data that is not plaintext fr…
coderdan Oct 19, 2026
07dc450
refactor(golang): read the call options and keyset selector with serd…
coderdan Oct 18, 2026
3477cc1
refactor(stack-encrypt): read query statistics from a frame with serd…
coderdan Oct 18, 2026
a668f9b
refactor(golang): read the cipher config and the test seed with serde…
coderdan Oct 18, 2026
da7ca75
refactor(stack-encrypt): read a context from its frame with serde, no…
coderdan Oct 18, 2026
381a4c7
refactor(stack-encrypt): read a record plan from its frame with serde…
coderdan Oct 18, 2026
42c8486
refactor(stack-encrypt): write the engine's answers with serde, not F…
coderdan Oct 18, 2026
91b6a22
test(stack-encrypt): spell test values as a test tree or as Rust valu…
coderdan Oct 18, 2026
e29a087
test(golang): spell the guest's test values as a test tree, not FfiValue
coderdan Oct 18, 2026
ca610d2
test(stack-encrypt): build the check_record fuzz target's plans as fr…
coderdan Oct 18, 2026
63d2183
refactor(stack-encrypt)!: remove FfiValue
coderdan Oct 18, 2026
2a4fe8f
fix(golang): a call whose context ends fails on its own, and leaves t…
coderdan Oct 18, 2026
94f995d
fix(golang): finish a device session's refresh in the background afte…
coderdan Oct 18, 2026
abc15c9
Merge pull request #1262 from cipherstash/feat/typed-control-messages
coderdan Oct 19, 2026
eca3b4f
Merge pull request #1264 from cipherstash/feat/remove-ffivalue
coderdan Oct 19, 2026
b5ed21e
Merge pull request #1263 from cipherstash/fix/go-client-cancel-isolation
coderdan Oct 19, 2026
592b66b
feat(stack-guest-abi): a step loop, so a guest operation pauses on it…
coderdan Oct 18, 2026
f3539d6
fix(eql): disable the ORE range domains where the ORE opclass is absent
coderdan Oct 19, 2026
7fcb8f0
feat(golang)!: the crypto guest steps instead of blocking on transpor…
coderdan Oct 18, 2026
7c1a0ab
Merge pull request #1258 from cipherstash/docs/integrity-model-review…
coderdan Oct 19, 2026
febb750
Merge remote-tracking branch 'origin/main' into chore/merge-main-into…
coderdan Oct 19, 2026
0800375
Merge pull request #1283 from cipherstash/chore/merge-main-into-next
coderdan Oct 19, 2026
1d4ae88
docs(stack-encrypt): ADR-0009 orders text, with no hedge
coderdan Oct 17, 2026
8b5fc57
feat(stack-encrypt)!: let an inverted Between range through, as SQL does
coderdan Oct 18, 2026
3004048
feat(stack-encrypt)!: order text, encrypting every order term through…
coderdan Oct 17, 2026
670dba9
feat(eql-bindings): produce the OPE-ordered EQL v4 types
coderdan Oct 18, 2026
9838d04
feat(eql-bindings): produce the date, timestamp and numeric EQL v4 types
coderdan Oct 18, 2026
36271cb
feat(stack-encrypt)!: order floats through cllw-ore's F64 target
coderdan Oct 18, 2026
596d160
test(golang,eql): seal the ordered EQL v4 types from Go, and compare …
coderdan Oct 18, 2026
f018a0e
test(golang,eql): seal the date, timestamp and numeric EQL v4 types f…
coderdan Oct 18, 2026
9c65e7e
Merge pull request #1235 from cipherstash/feat/stack-encrypt-text-ord…
coderdan Oct 19, 2026
15bbbc5
Merge pull request #1242 from cipherstash/feat/stack-encrypt-order-keys
coderdan Oct 19, 2026
32af771
Merge pull request #1266 from cipherstash/feat/eql-v4-ordered-ope-types
coderdan Oct 19, 2026
1c3e521
Merge pull request #1272 from cipherstash/feat/eql-v4-date-timestamp-…
coderdan Oct 19, 2026
e26d064
Merge remote-tracking branch 'origin/next' into feat/eql-v4-range-dom…
coderdan Oct 19, 2026
ad19081
fix(eql): refuse a range whose payload version is JSON null
coderdan Oct 19, 2026
8346d2c
fix(golang): queue callers past the guest's paused cap, and give step…
coderdan Oct 19, 2026
2b91de0
Merge pull request #1243 from cipherstash/feat/eql-v4-range-domains
coderdan Oct 19, 2026
a840933
Merge pull request #1265 from cipherstash/feat/guest-step-loop
coderdan Oct 19, 2026
4e75b3c
docs(plans): explore a JSON index for Stack Encrypt with a token chai…
coderdan Oct 17, 2026
1c145ce
docs(plans): record why plain SHA-256 holds for the token chain, keep…
coderdan Oct 18, 2026
f226f23
docs(plans): ship the JSON tree scheme as a new EQL v4 domain, not th…
coderdan Oct 18, 2026
1472eea
docs(plans): seal the root by default so no query can hand the server…
coderdan Oct 18, 2026
654b009
docs(plans): record epoched tokens as the future bound on how long a …
coderdan Oct 18, 2026
dc7d771
docs(plans): native jsonb containment over an element-nested projecti…
coderdan Oct 18, 2026
1ad0376
feat(stack-encrypt): let a target sealed under its own context opt in…
coderdan Oct 17, 2026
f41e258
feat(eql-bindings): query EQL v4 types through Stack Encrypt's typed …
coderdan Oct 17, 2026
fd55c20
docs(stack-encrypt,eql-bindings): say Answers needs LabelledTarget, a…
coderdan Oct 17, 2026
d827132
Merge pull request #1244 from cipherstash/feat/eql-v4-typed-queries
coderdan Oct 19, 2026
b6523a1
feat(eql): let an EQL v4 text search query carry only the terms its o…
coderdan Oct 18, 2026
6a1b2c0
feat(stack-encrypt)!: hand a target's query the index that answers it…
coderdan Oct 18, 2026
73583d2
feat(eql-bindings): produce TextSearch, its query carrying only its o…
coderdan Oct 19, 2026
213d998
test(golang): generate and seal a TextSearch field, each query carryi…
coderdan Oct 19, 2026
ba28168
feat(stack-encrypt)!: derive ore-rs 6-bit block ORE terms as a fifth …
coderdan Oct 19, 2026
b0c6cf4
feat(stack-encrypt): the JSON index, with node-local entries, a token…
coderdan Oct 19, 2026
faa3cb7
feat(eql): the json_tree domain family for Stack Encrypt's JSON index…
coderdan Oct 19, 2026
57becce
docs(plans): record where the JSON index implementation departs from …
coderdan Oct 19, 2026
358c0fd
Merge pull request #1274 from cipherstash/feat/eql-v4-text-search-opt…
coderdan Oct 19, 2026
a6619c4
feat(eql): compare ore-rs 6-bit block ORE in EQL v4, as ore_block_v2
coderdan Oct 19, 2026
9fa1312
feat(golang): read the ore_block index the engine reports
coderdan Oct 19, 2026
45a79a0
feat(eql-bindings): produce the block ORE EQL v4 types
coderdan Oct 19, 2026
ea92601
test(eql): let v4 own the JSON tree domains v3 does not in the coexis…
coderdan Oct 19, 2026
a05affa
Merge pull request #1280 from cipherstash/feat/eql-v4-block-ore
coderdan Oct 19, 2026
c6df166
test(stack-encrypt): kill the JSON index mutants the in-diff gate found
coderdan Oct 20, 2026
01c193b
perf(eql, stack-encrypt): store the json_tree projection, walk by par…
coderdan Oct 21, 2026
c98162f
fix(eql): keep json_tree_query out of the planner's inlining so the G…
coderdan Oct 21, 2026
319395d
test(eql, stack-encrypt): pin the stored projection's wire key and th…
coderdan Oct 21, 2026
c45bb79
feat(eql, stack-encrypt): chain json_tree tokens by ordinal and probe…
coderdan Oct 21, 2026
3860ecc
docs(eql, stack-encrypt): record the ordinal-chained walk's measureme…
coderdan Oct 21, 2026
6f74098
test(stack-encrypt): bound the children probe and pin the gated walk'…
coderdan Oct 21, 2026
b8c8ba4
test(stack-encrypt): drop the unreachable depth bound from the engine…
coderdan Oct 21, 2026
f76fe37
feat(stack-encrypt, eql): order json_tree leaves only at the paths th…
coderdan Oct 22, 2026
4f7c4fe
test(stack-encrypt): pin the laid-out plan's specs, Debug form and co…
coderdan Oct 22, 2026
dddb3a3
docs(stack-encrypt): record the storage measured with the ordering te…
coderdan Oct 22, 2026
810b687
test(stack-encrypt): pin that a laid-out plan refuses a clashing open…
coderdan Oct 22, 2026
6fe6128
Merge remote-tracking branch 'origin/next' into feat/json-index-stack…
coderdan Oct 22, 2026
725a27a
refactor(stack-encrypt): derive the JSON header's Debug with OpaqueDebug
coderdan Oct 22, 2026
60c12d2
Merge branch 'feat/json-index-stack-encrypt' into perf/json-tree-walk…
coderdan Oct 22, 2026
d292112
Merge branch 'perf/json-tree-walk-and-projection' into feat/json-tree…
coderdan Oct 22, 2026
37e02ab
feat(json-tree): spell the chain fields in base64, the ciphertext in …
coderdan Oct 23, 2026
9eb4b69
docs(json-tree): record that the derived nonce is rejected
coderdan Oct 23, 2026
55bbd66
docs(plans): rename the JSON index design to the json_tree index record
coderdan Oct 23, 2026
06af208
Merge branch 'docs/json-index-stack-encrypt-spike' into feat/json-ind…
coderdan Oct 23, 2026
b9ac367
docs: point at the renamed json_tree index record
coderdan Oct 23, 2026
cfd5dea
Merge branch 'feat/json-index-stack-encrypt' into perf/json-tree-walk…
coderdan Oct 23, 2026
9657508
Merge branch 'perf/json-tree-walk-and-projection' into feat/json-tree…
coderdan Oct 23, 2026
760e5bd
test(eql): hold the planner to the json_tree indexes on every support…
coderdan Oct 23, 2026
e7f782d
Merge remote-tracking branch 'origin/feat/json-tree-ordinal-chain' in…
coderdan Oct 23, 2026
47235ec
fix(docs): make the containment oracle flatten the stored document it…
coderdan Oct 23, 2026
a93a2f8
fix(docs): bring the token-chain prototype to the derivations the pla…
coderdan Oct 23, 2026
82fccbb
docs(plans): correct the json_tree record where it overstates what it…
coderdan Oct 23, 2026
0dd8a90
Merge branch 'docs/json-index-stack-encrypt-spike' into feat/json-ind…
coderdan Oct 23, 2026
5fb586f
Merge branch 'feat/json-index-stack-encrypt' into perf/json-tree-walk…
coderdan Oct 23, 2026
2b2a663
Merge branch 'perf/json-tree-walk-and-projection' into feat/json-tree…
coderdan Oct 23, 2026
fbb0954
Merge branch 'feat/json-tree-ordinal-chain' into feat/json-tree-gates
coderdan Oct 23, 2026
497c01e
fix(stack-encrypt): refuse a JSON document deeper than its sealed roo…
coderdan Oct 23, 2026
aa90e8b
fix(stack-encrypt): key the json_tree token step and member rank
coderdan Oct 23, 2026
151409c
fix(stack-encrypt, eql): bound what a stored json_tree document can m…
coderdan Oct 23, 2026
71ffa57
fix(stack-encrypt): print a JsonTerms as its node count
coderdan Oct 23, 2026
03a9223
fix(stack-encrypt): make AtPath<Eq> on the JSON index equality, not c…
coderdan Oct 23, 2026
fe7e457
fix(eql): block comparisons between a json_tree entry and plain jsonb
coderdan Oct 23, 2026
fd89e6a
docs(stack-encrypt): record the JSON index in the changelog
coderdan Oct 23, 2026
af54eda
style(stack-encrypt): rustfmt the json_tree review fixes
coderdan Oct 23, 2026
9b740b0
Merge branch 'feat/json-index-stack-encrypt' into perf/json-tree-walk…
coderdan Oct 23, 2026
500d508
Merge branch 'perf/json-tree-walk-and-projection' into feat/json-tree…
coderdan Oct 23, 2026
b91fba7
Merge branch 'feat/json-tree-ordinal-chain' into feat/json-tree-gates
coderdan Oct 23, 2026
c645a98
test(stack-encrypt): line up arrays as well as objects against the re…
coderdan Oct 23, 2026
612d5f5
Merge branch 'feat/json-index-stack-encrypt' into perf/json-tree-walk…
coderdan Oct 23, 2026
c2c6798
Merge branch 'perf/json-tree-walk-and-projection' into feat/json-tree…
coderdan Oct 23, 2026
765107e
Merge branch 'feat/json-tree-ordinal-chain' into feat/json-tree-gates
coderdan Oct 23, 2026
923364d
fix(stack-encrypt, eql-bindings): open a fallen-back walk to what the…
coderdan Oct 23, 2026
c1059d7
fix(eql): bound the json_tree walks by the document's size, not only …
coderdan Oct 23, 2026
014d25d
docs(eql): align the json_tree Phase 3 notes with the report they cit…
coderdan Oct 23, 2026
31d5da4
test(stack-encrypt): pin that the last attachment decides the fallbac…
coderdan Oct 23, 2026
fee616f
Merge branch 'perf/json-tree-walk-and-projection' into feat/json-tree…
coderdan Oct 23, 2026
7bf1d75
docs(stack-encrypt): put each_stored_form_opens_as_a_record_field's d…
coderdan Oct 23, 2026
cd8c060
Merge branch 'feat/json-tree-ordinal-chain' into feat/json-tree-gates
coderdan Oct 23, 2026
67b1f54
fix(eql, stack-encrypt): bind the child's selector into the json_tree…
coderdan Oct 23, 2026
d72d9fe
fix(stack-encrypt): refuse array positions in ordered json paths and …
coderdan Oct 23, 2026
d267735
test(stack-encrypt): fuzz the json wire decoders and refresh the fuzz…
coderdan Oct 23, 2026
d3d7f76
docs(eql): describe json_tree's base85 `c` and eight-byte `p` in type…
coderdan Oct 23, 2026
151fd5d
docs(stack-encrypt, eql-bindings): changelog the layout plan, the gat…
coderdan Oct 23, 2026
6d9ece2
docs(json-tree): count the walk's misses in the eight-byte parent tag…
coderdan Oct 23, 2026
f1f27f2
feat(stack-encrypt, eql-bindings): open a json_tree walk's rows throu…
coderdan Oct 23, 2026
63bec8f
fix(stack-encrypt): hold the json index's plaintext under Protected a…
coderdan Oct 23, 2026
c5d493f
Merge branch 'feat/json-tree-ordinal-chain' into feat/json-tree-gates
coderdan Oct 23, 2026
5dc9136
Merge branch 'next' into docs/json-index-stack-encrypt-spike
coderdan Oct 23, 2026
1a86672
test(stack-encrypt): pin JsonPath::covers on positions
coderdan Oct 23, 2026
0d441a2
Merge branch 'feat/json-tree-ordinal-chain' into feat/json-tree-gates
coderdan Oct 23, 2026
8598446
Merge branch 'docs/json-index-stack-encrypt-spike' into feat/json-ind…
coderdan Oct 23, 2026
53a63fa
Merge branch 'feat/json-index-stack-encrypt' into perf/json-tree-walk…
coderdan Oct 23, 2026
62f2132
Merge branch 'perf/json-tree-walk-and-projection' into feat/json-tree…
coderdan Oct 23, 2026
d3a47b1
Merge branch 'feat/json-tree-ordinal-chain' into feat/json-tree-gates
coderdan Oct 23, 2026
952d0be
Merge branch 'main' into next
coderdan Oct 23, 2026
8f9c9fb
chore(stack-encrypt)!: move to vitaminc 0.8, clww-ore 0.6 and ore-rs …
coderdan Oct 21, 2026
0563857
test(stack-encrypt): exclude KindOf::typed_null's equivalent default …
coderdan Oct 21, 2026
30a89e5
chore(deps): take clww-ore 0.6.0 and ore-rs 0.10.0 from crates.io
coderdan Oct 23, 2026
2ed8e17
chore(eql): build the block ORE timing harness on ore-rs 0.10
coderdan Oct 23, 2026
e88d6b8
docs(stack-encrypt): correct what the ORE upgrade made false
coderdan Oct 23, 2026
4cf7a5b
refactor(golang): take vitaminc only through stack-encrypt's re-exports
coderdan Oct 23, 2026
3c17e96
docs: describe the order indexes and a host's typed null for the reader
coderdan Oct 23, 2026
eb73756
fix(stack-encrypt): address review on the ORE upgrade
coderdan Oct 23, 2026
d830aea
feat(stack-encrypt): a data plan field says how it stores a null
coderdan Oct 21, 2026
3c9084f
feat(eql-bindings): a storage-only EQL type stores a None as long as …
coderdan Oct 21, 2026
089a9d9
feat(golang): an optional sealed field, declared over a pointer
coderdan Oct 21, 2026
06ce1de
test(eql): PostgreSQL stores a sealed null in a storage-only column
coderdan Oct 21, 2026
0a0600d
test(stack-encrypt): a sealed null only in a termless target, and onl…
coderdan Oct 21, 2026
b22be11
feat: a null has an equality term, and a sealed null sits beside one
coderdan Oct 21, 2026
d0ed4a1
test(stack-encrypt): a target query of a null needs a sealed field an…
coderdan Oct 21, 2026
2e23a58
test(stack-encrypt): a sealed null is as long as a value of every fix…
coderdan Oct 23, 2026
f3ade86
docs(stack-encrypt): point from_bytes at the plan null mode that pads…
coderdan Oct 23, 2026
410db32
docs(stack-encrypt): say a null has an equality term
coderdan Oct 23, 2026
c7b1205
fix(eql-bindings): seal no null of text from an Option<String>
coderdan Oct 23, 2026
d6e2a17
feat(golang): generate EncryptNull for a field that seals its nil
coderdan Oct 23, 2026
ab46dcd
Merge pull request #1327 from cipherstash/chore/vitaminc-0-8-ore-0-10
coderdan Oct 23, 2026
1f366a7
docs(eql): state what the json_tree entry order and extraction reveal
coderdan Oct 23, 2026
d01d547
ci(eql): gate ci-required on the per-version encryption suite
coderdan Oct 23, 2026
491b09c
test(eql): pin TOAST storage exactly and hold prepared-statement plans
coderdan Oct 23, 2026
17ac84f
docs(eql): do not claim an extracted value comes from the row it is l…
coderdan Oct 23, 2026
e219a94
Revert "fix(eql-bindings): seal no null of text from an Option<String>"
coderdan Oct 23, 2026
e6dc8f9
docs(eql-bindings): say a text null is not padded
coderdan Oct 23, 2026
bae6ce0
feat(stack-encrypt): order dates, timestamps and decimals
coderdan Oct 23, 2026
8b74c7d
feat(eql-bindings, golang): produce the ordered date, timestamp and n…
coderdan Oct 23, 2026
f8fc092
docs(eql): say the date, timestamp and numeric plaintexts are Stack E…
coderdan Oct 23, 2026
f048ac3
feat(stack-encrypt): serde for the order terms, and an owning from_bytes
coderdan Oct 23, 2026
da78393
feat(eql-bindings, eql): EQL v4 order terms are Stack Encrypt's typed…
coderdan Oct 23, 2026
e7a2fad
docs(eql): an EQL v4 order term is one hex string, checked when written
coderdan Oct 23, 2026
eb415b4
docs(eql): link U-003 from the changelog's directory, and show string…
coderdan Oct 23, 2026
c6e3af1
Merge pull request #1328 from cipherstash/feat/nullable-sealed-fields
coderdan Oct 23, 2026
e81e12c
Merge pull request #1337 from cipherstash/feat/order-dates-timestamps…
coderdan Oct 23, 2026
5a7d19e
Merge pull request #1340 from cipherstash/feat/eql-v4-order-term-types
coderdan Oct 23, 2026
52f9d39
ci: key the FFI cache and its workflow filters to the eql-bindings fi…
coderdan Oct 19, 2026
09d7365
ci(tests): run the live JS jobs only when a pull request can reach them
coderdan Oct 19, 2026
02e49dc
ci(tests): build EQL before the script tests, so the shipped-bundle c…
coderdan Oct 23, 2026
5eb9f2c
test(golang): run the Go SDK's rows and queries through EQL v4 in Pos…
coderdan Oct 19, 2026
0986a92
test(golang): query the block ORE EQL types in the PostgreSQL test
coderdan Oct 23, 2026
9f9db2d
Merge pull request #1290 from cipherstash/ci/path-filter-precision
coderdan Oct 23, 2026
a8f09b4
test(golang): fail the PostgreSQL task when a test did not run, or re…
coderdan Oct 23, 2026
8f2c8f8
test(golang): store a nil row in every EQL type in the PostgreSQL test
coderdan Oct 23, 2026
5d1791c
Merge pull request #1291 from cipherstash/ci/go-eql-postgres
coderdan Oct 23, 2026
1cdfb94
test(golang): check EQL v4 order with random values in PostgreSQL
coderdan Oct 23, 2026
5532dc9
test(golang): run every order edge as a query value
coderdan Oct 23, 2026
ccc7bdc
test(golang): take the order index from the round-trip test's list
coderdan Oct 23, 2026
1050ba6
Merge pull request #1344 from cipherstash/test/go-eql-order-properties
coderdan Oct 23, 2026
8930415
refactor(stack-encrypt): rename Plan::value().encrypt_as to encrypt_w…
coderdan Oct 24, 2026
e83644c
Merge branch 'feat/json-tree-ordinal-chain' into feat/json-tree-gates
coderdan Oct 24, 2026
b8d86cd
docs(eql): say an extracted entry proves its column, not its row
coderdan Oct 24, 2026
c31b0f3
test(eql): hold the json_tree planner test to the generic plan too
coderdan Oct 24, 2026
7d6a19e
fix(stack-encrypt): refuse JSON positions past PostgreSQL's integer
coderdan Oct 24, 2026
021603c
docs(stack-encrypt): show what a target Layout is for, with an example
coderdan Oct 24, 2026
ba0c2a2
docs(stack-encrypt): simplify the one-value plan and encrypt_with_lay…
coderdan Oct 24, 2026
e10c93b
refactor(stack-encrypt): keep a JSON index's ordered paths typed up t…
coderdan Oct 24, 2026
3999ed4
docs(stack-encrypt): record the JSON position bound in the CHANGELOG
coderdan Oct 24, 2026
14ccc86
refactor(eql-bindings): name the text encoding of each json_tree wire…
coderdan Oct 24, 2026
63582ee
fix(eql): bound every json_tree walk by the document's entry count
coderdan Oct 24, 2026
5003d08
docs(eql): mention the json_tree encoding newtypes in the changeset
coderdan Oct 24, 2026
99351a5
perf(stack-encrypt): move the fallback's nodes out of the sealed root…
coderdan Oct 24, 2026
fc9d3ef
Merge branch 'feat/json-tree-ordinal-chain' into feat/json-tree-gates
coderdan Oct 24, 2026
6c27ab1
docs(plans): note where the json_tree record is superseded on positio…
coderdan Oct 24, 2026
baa7458
Merge branch 'docs/json-index-stack-encrypt-spike' into feat/json-ind…
coderdan Oct 24, 2026
56264f2
Merge branch 'feat/json-index-stack-encrypt' into perf/json-tree-walk…
coderdan Oct 24, 2026
9cc4c8a
Merge branch 'perf/json-tree-walk-and-projection' into feat/json-tree…
coderdan Oct 24, 2026
4d672e1
Merge branch 'feat/json-tree-ordinal-chain' into feat/json-tree-gates
coderdan Oct 24, 2026
7d63656
Merge pull request #1250 from cipherstash/docs/json-index-stack-encry…
coderdan Oct 24, 2026
1260823
Merge branch 'next' into feat/json-index-stack-encrypt
coderdan Oct 24, 2026
ba8a940
Merge branch 'feat/json-index-stack-encrypt' into perf/json-tree-walk…
coderdan Oct 24, 2026
fc462af
Merge branch 'perf/json-tree-walk-and-projection' into feat/json-tree…
coderdan Oct 24, 2026
6127434
Merge branch 'feat/json-tree-ordinal-chain' into feat/json-tree-gates
coderdan Oct 24, 2026
6a4f1c2
fix(eql-bindings): make Base64Text and Base85Text guarantee their enc…
coderdan Oct 24, 2026
666f407
Merge branch 'feat/json-tree-ordinal-chain' into feat/json-tree-gates
coderdan Oct 24, 2026
8aa177a
test(scripts): count eql-bindings' encoding module among the stack-en…
coderdan Oct 24, 2026
fcf8f0c
Merge branch 'feat/json-tree-ordinal-chain' into feat/json-tree-gates
coderdan Oct 24, 2026
536d9e5
Merge pull request #1288 from cipherstash/feat/json-index-stack-encrypt
coderdan Oct 24, 2026
1c5e048
Merge pull request #1325 from cipherstash/perf/json-tree-walk-and-pro…
coderdan Oct 24, 2026
5652ec5
Merge pull request #1329 from cipherstash/feat/json-tree-ordinal-chain
coderdan Oct 24, 2026
b104982
Merge pull request #1336 from cipherstash/feat/json-tree-gates
coderdan Oct 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
41 changes: 41 additions & 0 deletions .cargo/mutants.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ exclude_re = [
'stack-encrypt/src/cipher\.rs:\d+:\d+: replace client_key_provider -> EnvKeyProvider with Default::default\(\)$',
'stack-encrypt/src/target/pending\.rs:443:9: replace <impl IntoFuture for Pending<.*>>::into_future -> Self::IntoFuture with Default::default\(\)$',
# stack-encrypt — equivalent.
# An operator and an index are unit structs, whose `Default` is the value
# `clone` and `case_sensitive` already return.
'stack-encrypt/src/op(/mod)?\.rs:\d+:\d+: replace <impl Clone for Matches<C>>::clone -> Self with Default::default\(\)$',
'stack-encrypt/src/op(/mod)?\.rs:\d+:\d+: replace Matches::case_sensitive -> Matches<CaseSensitive> with Default::default\(\)$',
'stack-encrypt/src/target/index\.rs:\d+:\d+: replace <impl Clone for Match<O>>::clone -> Self with Default::default\(\)$',
'stack-encrypt/src/cipher\.rs:\d+:\d+: replace StackCipher<FromEnv>::builder -> StackCipherBuilder with Default::default\(\)$',
'stack-encrypt/src/sem/mod\.rs:\d+:\d+: replace <impl MatchConfig for DefaultMatch>::options -> MatchOptions with Default::default\(\)$',
# Both unit-context conversions explicitly return Self::default().
Expand All @@ -80,6 +85,42 @@ exclude_re = [
# the empty list (`dynamic::target::NoTargets`), which a test asserts on
# and `resolve` turns into `TargetError::NoTargets`; `vec![]` is the body.
'stack-encrypt/src/dynamic/target\.rs:\d+:\d+: replace <impl TargetResolver for NoTargets>::targets -> Vec<TargetDescriptor> with vec!\[\]$',
# A passthrough, and a typed null as any null, has no kind:
# `KindOf::passthrough` and `KindOf::typed_null` return `Ok(None)`, which
# is `Ok(Default::default())`. `a_frame_names_its_kind` asserts the first.
'stack-encrypt/src/dynamic/value_frame\.rs:\d+:\d+: replace <impl Sink for KindOf>::(passthrough|typed_null) -> Result<Self::Ok, DecodeError> with Ok\(Default::default\(\)\)$',
# `model`'s `admits` guard on a date, decimal or undefined value is checked
# again by vitaminc on every path that reaches it: the frame writer behind
# `Modeled` and `ModelOnly` refuses an inadmissible logical value
# (`FrameWriteError::Invalid`, mapped to the same `Expected`), and
# `ValueFrame::check` only walks frames `Frame::parse` has validated. So
# `true` there refuses the same values with the same error. The guard stays
# so the model says what it holds without leaning on the writer behind it.
'stack-encrypt/src/dynamic/value_frame\.rs:\d+:\d+: replace match guard logical\.admits\(&value\) with true in model$',
# A serde visitor's `expecting` writes only the "expected ..." half of a
# serde error's message, and no caller of these three reads that message:
# a context, statistics and a plan's root are each refused with one fixed
# `Reason` (`ContextKind`, `NotStats`, `NotAnObject`), and the plan's
# field-level reasons are read from the error's path, so writing nothing
# refuses the same input with the same error.
'stack-encrypt/src/dynamic/(context|query|record)\.rs:\d+:\d+: replace <impl (Visitor<\x27de> for ContextVisitor|serde::Deserialize<\x27de> for Confidence>::deserialize::<impl serde::de::Visitor<\x27_> for V|Deserialize<\x27de> for PlanWire>::deserialize::<impl Visitor<\x27de> for V)>::expecting -> fmt::Result with Ok\(Default::default\(\)\)$',
# The same for the visitor that reads a refused plan's keys back
# (`entry_key`): its error is discarded (`.ok()`), so its message is never
# read at all.
'stack-encrypt/src/dynamic/record\.rs:\d+:\d+: replace entry_key::<impl Deserialize<\x27de> for Keys>::deserialize::<impl Visitor<\x27de> for V>::expecting -> fmt::Result with Ok\(Default::default\(\)\)$',
# The JSON index. `unhex` joins a high nibble shifted into the top four
# bits with a low nibble below 16: the bits never overlap, so `^` is `|`.
'stack-encrypt/src/json/mod\.rs:\d+:\d+: replace \| with \^ in unhex$',
# `JsonPath::root` is `Self::default()`.
'stack-encrypt/src/json/path\.rs:\d+:\d+: replace JsonPath::root -> Self with Default::default\(\)$',
# The sealed root's `None` token: with that arm gone, the root falls to
# the arm that wraps its parent's token, and the root has no parent, so
# it is `None` there too. `the_sealed_root_has_no_token_and_its_fields_are_heads`
# pins the value; the arm stays so the match says it.
'stack-encrypt/src/json/derive\.rs:\d+:\d+: delete match arm \(0, true\) in Walker<\x27_>::visit$',
# A document always has a root, so its terms are never empty: `false` is
# the value `is_empty` returns. The `true` replacement is still caught.
'stack-encrypt/src/json/derive\.rs:\d+:\d+: replace JsonTerms::is_empty -> bool with false$',
]

# Headroom over the measured baseline before a slow-but-correct mutant is
Expand Down
6 changes: 6 additions & 0 deletions .changeset/chacha20-0-10-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@cipherstash/protect-ffi': patch
'@cipherstash/auth': patch
---

Build the native binaries against `chacha20` 0.10.2. Versions 0.10.0 and 0.10.1 were yanked: on an x86 CPU without AVX2, their SSE2 fallback for the random number generator used an SSE4.1 instruction it had not checked the CPU for. A CPU without SSE4.1 (one from before 2008, or a virtual machine using QEMU's default `qemu64` CPU model) would crash with an illegal-instruction error. Every other CPU produced correct random numbers, so randomness was never weakened. No API change.
5 changes: 5 additions & 0 deletions .changeset/eql-bindings-optional-storage-only.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cipherstash/eql": patch
---

`eql-bindings` (the Rust crate released with this package): an EQL v4 type whose terms a null has, a storage-only type (`Date`, `Integer`, `Text`, ...) or one whose only term is equality's (`DateEq`, `IntegerEq`, `TextEq`, ...), now also implements `EncryptFrom` and `DecryptInto` for an `Option` of its plaintext, and its query twin `EncryptFrom` for one. For a type of fixed width a `None` seals as a typed null as long as a value (vitaminc 0.8), so an optional column does not show which rows are absent. For text it seals as a null that is not padded, since text's ciphertext is as long as the text, so its length may show that the value is absent. Either way it opens as `None`; its `hm` is the one term every null shares, and the query of a `None` finds the stored nulls with `=`. A value seals exactly as before. The by-name dispatch (`encryption::targets`) reads, opens and queries these types through the `Option`; a type with an order or match term still refuses a null. eql-bindings' own `Date`, `Timestamp` and `Decimal` plaintexts declare their fixed width to vitaminc, so their `None` is padded too. The SQL bundle and the TypeScript types do not change.
7 changes: 7 additions & 0 deletions .changeset/eql-json-tree-domain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@cipherstash/eql": minor
---

**EQL v4 gains the `json_tree` domain family: `public.eql_v4_json_tree`, an encrypted JSON document stored as one entry per node, with `@>` and `<@` that agree with PostgreSQL's own `jsonb @>` across array elements.** The family is new beside `public.eql_v4_json` and is not a port of the v3 SteVec surface: it is what Stack Encrypt's JSON index writes. A document's entries each carry a path selector `s` and a value selector `vs` (containment is a set comparison over the pair), the node's own ciphertext `c` (its label, kind and scalar value; a document's ciphertext is linear in its size, where a SteVec document repeats every subtree at every level), and a token chain (`p`, `w`, `o`) that lets core PostgreSQL walk the subtree under a node from one client-derived token: `eql_v4.json_tree_subtree(doc, token)`, `json_tree_subtree_at(doc, token, selector)`, `json_tree_children` and `json_tree_child_count`. By default the root is sealed, so no query can hand the server a token for the whole column. Containment projects a stored document into an element-nested shape from its group tags (`n`, `g`), `eql_v4.json_tree_query(doc)`, and compares it with the needle (`eql_v4.query_json_tree`) by native `jsonb @>`, so each needle array element must fit inside one stored element, which closes the cross-element false positives of selector-set containment (#1231) for this family; a GIN index on `(eql_v4.json_tree_query(col)::jsonb) jsonb_path_ops` serves it. `->` by selector returns an entry that opens on its own (`public.eql_v4_json_tree_entry`, with the header and ordinal grafted), and `eql_v4.query_json_tree_leaf` orders an extracted number or string leaf with `<`, `<=`, `>`, `>=`. Every other native jsonb operator on the column is blocked, as on the other EQL domains. EQL v4 only (`-- ONLY EQL VERSION: 4`); the v3 bundle is unchanged. The `eql-bindings` crate carries the hand-written `v4::json_tree` types with Stack Encrypt's `EncryptFrom` / `DecryptInto` for the document and the entry.

Why. Stack Encrypt had no JSON index: the operators (`Contains`, `ContainedBy`, `AtPath`) were declared and answered by nothing, and the v4 JSON wire format was unconstrained by anything shipped. This is Phase 1 and 2 of the `json_tree` index's phased plan (#1249), implemented against `docs/plans/2026-10-17-json-tree-index.md`, whose "Implementation notes" section records where the code deviates from the design.
13 changes: 13 additions & 0 deletions .changeset/eql-json-tree-ordinal-chain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@cipherstash/eql": minor
---

EQL v4 `json_tree` (unreleased): the token chain is derived by ordinal and the walk probes to the first miss.

A stored entry now carries four fields, `s`, `c`, `p` and `op`. The value selector `vs` lives only in the document's projection `q`, which the engine now reads back as the projection instead of rebuilding it from the entries; the group tags `n` and `g` are gone with it, since nothing read them once `q` was stored. The wrapped token `w` and the ordinal `o` are gone too: a child's token is `H("t" ‖ t(parent) ‖ s ‖ LE32(o))`, `s` being the child's own selector, which the server derives as it walks, and the ordinals under a node are dense from zero, so the walk probes them in turn and stops at the first miss. A subtree of `N` nodes costs about `2N` probes (a SHA-256 and a lookup each) and `N` token hashes whatever the document's width, where it cost a probe for every ordinal up to the document's widest node at every node visited. The entry validator accepts the four fields only, so a document written by the earlier build of this unreleased family is refused.

The client can derive a token only for a chain head and the array positions that directly follow it, since an object member's ordinal is a rank among its siblings' keys. `JsonSubtreeKey::gates()` gives the rest of a path as one gate per step, a selector, or `#n:<selector>` for an array position with the array elements' selector, and `eql_v4.json_tree_subtree_at(doc, token, gates text[], budget DEFAULT 64)` walks them, replacing the earlier `json_tree_subtree_at(doc, token, selector, budget)`. `json_tree_children` and `json_tree_child_count` take the same `gates`, optional and empty by default. A gated walk returns the node the gates reach with `d = 0` and its descendants beneath it, so a wildcard reaches several nodes and opens as a list; `json_tree_subtree(doc, token, budget)` is now `json_tree_subtree_at` with no gates and still returns the descendants of the token's node from `d = 1`. Past the budget a walk still returns the sealed root alone, with `j = 0` and `d = 0`. `eql_v4_internal.json_tree_unwrap`, `json_tree_xor16` and `json_tree_fanout` are removed; `eql_v4_internal.json_tree_child_token(token, s, o)` is added. Binding the child's selector into its token, and the element selector into a position gate, is what makes a position name an array element only: an ordinal alone is an element's position or an object member's rank, so in a row whose node at the path is an object, `$.a[0]` would otherwise reach the member that ranks first, where `jsonb` has no node.

**Byte encodings.** Every field the SQL compares, derives or decodes is padded standard base64, as PostgreSQL's `encode(x, 'base64')` writes it: the selectors `s`, the `s` and `vs` pairs of `q`, the parent tag `p`, the ordering term `op`, and the tokens and gates `json_tree_subtree_at`, `json_tree_children` and `->` take, where they were hex; the header `h` was base64 already. The ciphertext `c`, which no SQL function decodes, is RFC 1924 base85. The parent tag `p` is the first eight bytes of its hash, since it is a lookup key within one document and nothing authenticates through it. `eql_v4_internal.json_tree_ope_cllw` is added for `eql_v4.ord_term`, because the `ope_cllw(jsonb)` the scalar types share reads hex. A document written by the earlier build of this unreleased family is refused by the engine. In `eql-bindings` each json_tree wire type names its encoding, holding an `encoding::Base64Text` or, for `c`, an `encoding::Base85Text`; the wire form is the same string. The encoding type guarantees its text is in that encoding: a value is made only by `encode`, from bytes, or by deserializing, which decodes the text and refuses text that is not in the encoding, so a payload with a field in the wrong encoding fails to deserialize. Re-encoding 1,000 stored rows of each benchmark corpus: a nested document measures 22% smaller on disk (`pg_column_size` 40,808 to 31,894 bytes) and a flat one 12% (1,596 to 1,398).

Measured on 10,000 and 100,000 rows of a nested corpus (about 213 entries a document), query-only medians: subtree walks 30 to 55% faster (a 122-entry subtree walked out, 23 ms to 11 ms), `json_tree_children` and `json_tree_child_count` 6 to 9%, a stored nested document 25% smaller (heap 810 MB to 621 MB at 10,000 rows), containment and field queries unchanged within the run's noise.
5 changes: 5 additions & 0 deletions .changeset/eql-json-tree-planner-and-leakage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cipherstash/eql": patch
---

EQL v4 `json_tree` (unreleased): the reference docs gain "What an encrypted JSON tree reveals" (`docs/reference/json-tree-leakage.md`), one page on what a stored row shows the database at rest (including the row's shape, which the stored depth-first entry order gives away), what each query type hands it, what is and is not authenticated, and the side-by-side with v3 `ste_vec`. The encryption test suite now holds the planner to the GIN and btree indexes with every setting at its default, on inline and TOASTed documents, for one-shot and prepared statements, and CI runs that suite on every supported PostgreSQL version.
15 changes: 15 additions & 0 deletions .changeset/eql-json-tree-walk-and-projection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
"@cipherstash/eql": minor
---

**The `json_tree` family's read path no longer pays for the document's size per query.** Three changes to the EQL v4 `json_tree` SQL, each measured (cipherstash/benches, `report/JSON_TREE_COMPARISON.md` at 57abcf9) on a 10,000-row corpus of nested documents (about 220 nodes each) where the shipped surface was one to four orders of magnitude behind native `jsonb`:

- **A stored document carries its own containment projection, `q`.** The client writes the document's `{s, vs}` pairs nested by array element beside `sv`, and `eql_v4.json_tree_query(doc)` now reads that field instead of rebuilding the projection from the group tags on every call. The GIN index recheck, which runs the projection once per candidate row, was the whole cost of `@>` on a nested document: 75 ms for ten rows, 16 s for a two-thousand-row result set, 44 s to build the index on 10,000 rows. With the projection stored the same queries measure in the low milliseconds and the index builds in seconds. `json_tree_query` returns `jsonb` rather than the needle domain, since the domain's CHECK would run per recheck; the document's own CHECK validates `q` when the row is written. It is a plpgsql function costed at 1000 rather than an inlinable SQL one: inlined to `value -> 'q'` the planner costs the filter as one operator, and a column of large documents is TOASTed out of the heap, so a sequential scan over it looked nearly free and was chosen over the GIN index while in fact decompressing every row (1.5 s for a one-row match on 10,000 rows; 0.5 to 0.7 ms through the index). The index expression is `(eql_v4.json_tree_query(col)) jsonb_path_ops`; the `::jsonb` cast earlier guidance wrote is harmless and no longer needed. **Wire change:** `q` is required in `public.eql_v4_json_tree`, and a document written by the earlier build of this unreleased family is refused by the domain CHECK.
- **The token-chain walk reads the document once.** `json_tree_subtree`, `json_tree_subtree_at`, `json_tree_children` and `json_tree_child_count` computed each parent tag inside a scan of `sv`, once per (node, ordinal, entry); a 244-entry subtree took ten seconds. The walk now builds one map of the document's entries keyed by parent tag and looks each computed tag up in it, so a level costs its fan-out in SHA-256 evaluations and the document is never scanned per node. The same subtree walks out in 23 ms; `children` and `child_count` in 1.6 ms. The walk is also bounded by the document's size, so a stored document whose unauthenticated chain fields claim a huge ordinal, or loop back to an ancestor, can no longer keep a query running until `statement_timeout`.
- **A walk has a budget, and past it returns the sealed root.** `json_tree_subtree(doc, token, budget DEFAULT 64)` and `json_tree_subtree_at(doc, token, selector, budget DEFAULT 64)` stop once the subtree exceeds `budget` entries and return the root entry alone, with `d = 0`, when the document's root is sealed: the root's ciphertext is the whole document at about the plaintext's size, where the walk returns some four hundred characters per entry and pays the fan-out in hashes per node, so past a dozen or so entries the whole document is cheaper on both sides. The client opens the root and takes the walked path over it, and gets what the walked rows open to. The rows are opened through the key that keyed the walk, which carries the path it was derived from and knows from its gates which walk the rows came from: `key.open(rows)` in `stack-encrypt`, `JsonTreeSubtree::from_key(&key, rows)` in `eql-bindings`. Rows cannot be opened without it, so a document that grows past the budget does not break a caller. A budget of `0` never falls back; a token that names no node still yields no row; a document whose root is not sealed is always walked out.

Also: `eql_v4.json_tree_path_query_first`, the function `->` and the ordering comparisons extract through, is costed at 1000 so a prepared statement's generic plan keeps the functional btree on `eql_v4.ord_term(col -> sel)` instead of filtering a sequential scan (16.9 ms down to 0.11 ms after the fifth execution). `eql_v4_internal.json_tree_group`, the server-side projection builder, is removed.

The `eql-bindings` crate's `JsonTreeDocument` gains the `q` field and `JsonTreeSubtree` becomes a struct of the rows and the key that keyed the walk; `stack-encrypt`'s `JsonDocument` writes `q` on the wire and ignores it on the way in, `JsonPath::select` evaluates a path over a value, and `JsonSubtreeKey::path` and `open`, `JsonSubtree::path` and `is_sealed_root` carry the fallback. EQL v4 only; the v3 bundle is unchanged.

**The leaf ordering term `op` is opt-in per path.** A stored leaf carried the order-preserving term on every number and string, about 80 bytes each and the largest field of a nested document, whether or not anything ordered by it. Now the JSON index's options name the paths that order (`{"json": {"ordered": ["$.age", "$.orders[*].total"]}}` on the data plan; `JsonOptions::ordering([...])` in Rust), a wildcard covering every element of an array, and no path is ordered by default. A position in an ordered path (`$.scores[2]`), or in the path an ordering asks at, is refused: the comparison extracts by selector, which reads a position as the wildcard and reaches the first element, never the one named. An ordering query at a path the index does not order is refused before any key loads rather than silently matching no row. The SQL is unchanged: `eql_v4.ord_term` was already NULL for a leaf without a term. `eql-bindings` gains `v4::JsonTree`, the `json_tree` layout under options, and `stack-encrypt` gains `target::Layout` and `Plan::value().encrypt_with_layout(layout)`, a plan laid out by a value whose queries run under its options.
5 changes: 5 additions & 0 deletions .changeset/eql-lints-own-domains.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cipherstash/eql': patch
---

`eql_v3.lints()` now judges only EQL's own `public.eql_v3_*` domains. It used to take every `jsonb` domain in `public`, so a database with another set of encrypted domains installed beside EQL v3 got thousands of false `inlinability_*` errors from the self-check.
Loading
Loading