Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
239 commits
Select commit Hold shift + click to select a range
787782a
docs(adr): one value model, three encodings in vitaminc, EQL v4 by pr…
coderdan Oct 8, 2026
b551942
docs(plans): put vitaminc at the bottom of the order and equality ter…
coderdan Oct 11, 2026
54f1ad0
docs(adr): correct ADR-0002 on what EQL v4's separate names enforce
coderdan Oct 12, 2026
c5bca32
docs(adr): fold the layering plan into ADR-0002 and answer its review
coderdan Oct 12, 2026
e5c78bc
docs(adr): say which kinds have no target yet, and name OPERATOR(publ…
coderdan Oct 13, 2026
ceb7503
refactor(eql): write the SQL source with schema and version placeholders
coderdan Oct 9, 2026
cc0e5ed
chore(eql): regenerate the scalar SQL surface with placeholders
coderdan Oct 9, 2026
fdda4de
fix(eql): keep the placeholder build's gates able to fail
coderdan Oct 12, 2026
2e2fabc
fix(eql): tighten the placeholder renderer's CLI, gates and checks
coderdan Oct 13, 2026
4a04c66
fix(eql): read the rendered SQL in the Doxygen filter instead of re-r…
coderdan Oct 13, 2026
82e7ea8
feat(eql-bindings): generate EQL v4 bindings and derive Stack Encrypt…
coderdan Oct 12, 2026
d8c68e7
feat(eql): build the eql_v4 bundle beside eql_v3
coderdan Oct 12, 2026
06be2bb
test(golang): expect EQL v4 payloads from the stack-encrypt guest
coderdan Oct 12, 2026
65b9875
fix(eql): make the v4 isolation gate and both lints hold with two bun…
coderdan Oct 12, 2026
a7ae2ae
fix(eql-bindings): give v4 inventory entries v4 schema ids, and pin t…
coderdan Oct 12, 2026
7ea64a4
fix(eql): make the v4 isolation gate check versions positively
coderdan Oct 13, 2026
d21ef3f
refactor(eql-bindings): one SchemaVersion generic over its version
coderdan Oct 13, 2026
f3af167
test(eql): pin the cross-version fallback to jsonb = jsonb from the c…
coderdan Oct 13, 2026
63a9bd7
fix(eql): make the pre-commit drift gate run in the monorepo
coderdan Oct 13, 2026
4acfd3f
feat(eql-bindings): produce the unordered EQL v4 number, boolean and …
coderdan Oct 12, 2026
a078a7a
test(eql-bindings): update the target unit tests for a producible Text
coderdan Oct 12, 2026
4fa866b
fix(eql-bindings): hold IntegerEq and BigintEq back until vitaminc 0.6
coderdan Oct 12, 2026
b133bcd
fix(eql-bindings, stashgen): pin the scalar leaves, compare floats by…
coderdan Oct 13, 2026
0a04a90
feat(eql-bindings): produce EQL v4 TextMatch from Stack Encrypt's mat…
coderdan Oct 12, 2026
5ed5202
fix(eql-bindings): pin TextMatch's filter at k = 6, m = 2048 and pack…
coderdan Oct 12, 2026
c4ec6dd
fix(eql-bindings, stashgen): document TextMatch's limits, and teach t…
coderdan Oct 13, 2026
bb32388
test(golang): prove the EQL v4 types from Go, against Rust and Postgr…
coderdan Oct 12, 2026
4e28bba
test(golang): send Go-sealed v4 rows through PostgreSQL, and drop the…
coderdan Oct 12, 2026
df9f35f
test(golang): hand today's Go-sealed rows to Rust, and keep the fixtu…
coderdan Oct 13, 2026
c242932
docs(golang): lead the encrypt quickstart with EQL v4 columns
coderdan Oct 13, 2026
5be2edb
chore: open next, the integration branch for the EQL v4 and Stack Enc…
coderdan Oct 16, 2026
a55e6c8
Merge pull request #1139 from cipherstash/docs/adr-value-encodings-eq…
coderdan Oct 16, 2026
595bb65
Merge pull request #1147 from cipherstash/refactor/eql-schema-placeho…
coderdan Oct 16, 2026
5f5f23f
Merge pull request #1161 from cipherstash/feat/eql-v4-bundle
coderdan Oct 16, 2026
542b5f7
Merge pull request #1162 from cipherstash/feat/eql-v4-bindings
coderdan Oct 16, 2026
2d899c0
Merge pull request #1163 from cipherstash/feat/eql-v4-scalar-types
coderdan Oct 16, 2026
0dc292e
Merge pull request #1164 from cipherstash/feat/eql-v4-text-match
coderdan Oct 16, 2026
c5cf0c9
Merge pull request #1165 from cipherstash/test/golang-eql-v4
coderdan Oct 16, 2026
d9de4b3
docs(adr): ADR-0009, operators select the index and a query term is n…
coderdan Oct 13, 2026
ee0e459
docs(adr): ADR-0009 review round, with sqlx and language-SDK appendices
coderdan Oct 13, 2026
ceb1e63
docs(adr): ADR-0009 appendix B sketches a Stack Encrypt TypeScript SDK
coderdan Oct 13, 2026
8c483cb
docs(adr): ADR-0009 appendix B names the next major of @cipherstash/s…
coderdan Oct 13, 2026
af98f7a
docs(adr): ADR-0009 second review round
coderdan Oct 14, 2026
497d86a
docs(adr): ADR-0009 carries #1190's signatures, and a smaller k is worse
coderdan Oct 14, 2026
3f90080
docs(adr): ADR-0009 third review round
coderdan Oct 16, 2026
a6de2dc
feat(stack-encrypt)!: a query names an operator, not an index
coderdan Oct 13, 2026
44b2e2c
fix(stack-encrypt): address the review of the operator-typed query
coderdan Oct 13, 2026
a69f2e9
refactor(stack-encrypt): the query chain starts with the operator and…
coderdan Oct 13, 2026
ce04767
fix(stack-encrypt): address the second review of the operator-typed q…
coderdan Oct 17, 2026
cfad6fe
feat(stack-encrypt): verify a match query's rows after decrypt
coderdan Oct 13, 2026
59bdc7b
fix(stack-encrypt): address the review of match verify
coderdan Oct 13, 2026
67a1614
fix(stack-encrypt): address the second review of match verify
coderdan Oct 17, 2026
5aeb027
refactor(stack-encrypt): name what a query keeps to check a row its V…
coderdan Oct 17, 2026
0a56ced
feat(stack-encrypt): size a match query's fetch with target_limit
coderdan Oct 13, 2026
13e250a
fix(stack-encrypt): address the review of target_limit
coderdan Oct 13, 2026
ff2a4c4
fix(stack-encrypt): bound the Poisson quantile's work, and pin its edges
coderdan Oct 13, 2026
6454513
fix(stack-encrypt): loop the Poisson window by offset, under the cap
coderdan Oct 13, 2026
8eb09ee
docs(stack-encrypt): the query, not the needle, in target_limit's prose
coderdan Oct 14, 2026
2ec5306
fix(stack-encrypt): address the second review of target_limit
coderdan Oct 17, 2026
67274c7
feat(stack-encrypt): store a token-less match value as the empty filt…
coderdan Oct 14, 2026
a9e4857
fix(stack-encrypt): address the review of the empty match filter
coderdan Oct 16, 2026
9dbafcd
fix(eql-bindings): refuse match text with no tokens for EQL v4 TextMa…
coderdan Oct 16, 2026
c816046
fix(stack-encrypt): address the second review of the empty match filter
coderdan Oct 17, 2026
70dcc17
feat(stack-encrypt): the ordering operators, Between as one term, and…
coderdan Oct 14, 2026
5a53a29
fix(stack-encrypt): seal Ordered
coderdan Oct 16, 2026
21b7deb
feat(stack-encrypt): declare the JSON operators Contains, ContainedBy…
coderdan Oct 14, 2026
90714bb
feat(stack-encrypt)!: seal through vitaminc ADR 0001 so a value is de…
coderdan Oct 15, 2026
8daa5ae
fix(stack-encrypt): address the second review of the ordering operators
coderdan Oct 17, 2026
6eff76a
fix(stack-encrypt): address the second review of the JSON operators
coderdan Oct 17, 2026
ea275c5
test(stack-encrypt): build the fuzz crate against the same vitaminc, …
coderdan Oct 15, 2026
a285ffc
feat(golang)!: carry transport frames between the Go module and both …
coderdan Oct 15, 2026
9628167
test(stack-encrypt): pin each cipher half's refusal and a host's u8, …
coderdan Oct 15, 2026
d03f8aa
feat(eql)!: build eql-bindings' stack-encrypt feature on vitaminc ADR…
coderdan Oct 16, 2026
bbc4075
build!: pin vitaminc to the commit ore.rs builds against, and take it…
coderdan Oct 16, 2026
1bb42ab
fix(stack-guest-abi): wipe text a guest hands back, and pin the Go mo…
coderdan Oct 16, 2026
beb3074
fix(guests): hand the host output buffers with no spare capacity, so …
coderdan Oct 16, 2026
59e32bb
test(stack-encrypt): cover every FfiValue Debug branch
coderdan Oct 16, 2026
c45b712
build(stack-encrypt): drop the unused vitaminc-aead-frame dependency
coderdan Oct 16, 2026
1a7fff5
fix(ci): package without a registry build while a crate is pinned to git
coderdan Oct 17, 2026
064c104
fix(stack-encrypt): address the second review of the vitaminc ADR 000…
coderdan Oct 17, 2026
989f99a
fix(ci): leave out a crate whose git-pinned dependency has no crates.…
coderdan Oct 17, 2026
17edce0
build!: require vitaminc 0.6.0 from crates.io, and drop the git pin a…
coderdan Oct 17, 2026
b6ee8a3
build(stack-encrypt)!: version stack-encrypt and stack-encrypt-derive…
coderdan Oct 17, 2026
9686e9d
feat(stack-encrypt)!: derive equality and match terms through vitamin…
coderdan Oct 15, 2026
4070909
feat(stack-encrypt)!: walk a dynamic value to its scalar as vitaminc …
coderdan Oct 15, 2026
bb06ead
feat(golang)!: walk a term's frame in place in the encrypt guest and …
coderdan Oct 15, 2026
c3a3ed9
feat(eql)!: compare TextEq text in Unicode 16 NFC through Stack Encry…
coderdan Oct 15, 2026
25a0baf
test(eql): re-pin the v4 match fixtures under the normalized match te…
coderdan Oct 16, 2026
6fcf900
fix(stack-encrypt): refuse a boolean's order term on the typed path t…
coderdan Oct 16, 2026
7cdc438
feat(stack-encrypt): let a binding query a plan field by operator, an…
coderdan Oct 15, 2026
2e6e584
fix(stack-encrypt): keep a refused term's kind when a record is written
coderdan Oct 16, 2026
ffbf57b
feat(golang): export se_query_term, se_verify and se_target_limit so …
coderdan Oct 15, 2026
acbfc45
fix(stack-encrypt): address the second review of normalized terms
coderdan Oct 17, 2026
9071b05
docs(stack-encrypt): amend ADR-0007 for queries named by operator, pr…
coderdan Oct 15, 2026
63739fe
test(stack-encrypt): pin a match index's verifier, which a query chai…
coderdan Oct 17, 2026
abb99fc
docs(stack-encrypt): say TextMatch is produced and answers no operato…
coderdan Oct 16, 2026
58718af
fix(stack-encrypt, guest): refuse unnormalizable equality text before…
coderdan Oct 16, 2026
66f4f76
chore(biome): leave the generated query_operators.json fixture alone
coderdan Oct 16, 2026
451d452
fix(stack-encrypt): refuse invalid match options before a query cuts …
coderdan Oct 16, 2026
55e5cf3
feat(stack-encrypt): let a binding ask which operators a plan field a…
coderdan Oct 15, 2026
60591a9
fix(golang): address the second review of the operator exports
coderdan Oct 17, 2026
fc1b4f5
feat(stack-encrypt)!: TextMatch answers matches through its query twi…
coderdan Oct 17, 2026
cdd07e1
feat(golang)!: generate one query method per operator the engine answ…
coderdan Oct 15, 2026
ea67ace
test(golang): run a matches query and verify its rows against Postgre…
coderdan Oct 15, 2026
7a6b2ac
docs(golang): show the query methods, the database/sql query and the …
coderdan Oct 15, 2026
59e13f1
test(stack-encrypt): refuse a match query twin whose bf repeats a pos…
coderdan Oct 17, 2026
36703d0
Merge pull request #1177 from cipherstash/docs/adr-operator-query-terms
coderdan Oct 17, 2026
c57bee8
Merge pull request #1190 from cipherstash/feat/stack-encrypt-operator…
coderdan Oct 17, 2026
5d76de3
Merge pull request #1191 from cipherstash/feat/stack-encrypt-match-ve…
coderdan Oct 17, 2026
45ff7b5
Merge pull request #1192 from cipherstash/feat/stack-encrypt-target-l…
coderdan Oct 17, 2026
25371aa
Merge pull request #1206 from cipherstash/feat/stack-encrypt-short-ma…
coderdan Oct 17, 2026
ab2f6d0
Merge pull request #1208 from cipherstash/feat/stack-encrypt-ordering…
coderdan Oct 17, 2026
40cf522
Merge pull request #1209 from cipherstash/feat/stack-encrypt-json-ope…
coderdan Oct 17, 2026
94fd78a
Merge pull request #1213 from cipherstash/feat/stack-encrypt-vitaminc…
coderdan Oct 17, 2026
fff7905
Merge pull request #1214 from cipherstash/feat/stack-encrypt-dynamic-…
coderdan Oct 17, 2026
36836e1
Merge pull request #1215 from cipherstash/feat/stack-encrypt-operator…
coderdan Oct 17, 2026
68a2051
fix(golang): address the review of the operator query methods
coderdan Oct 17, 2026
ce76681
docs(golang): give the matches example a field that answers it, and q…
coderdan Oct 17, 2026
9c0bdb3
fix(golang): keep generated files at version 1
coderdan Oct 17, 2026
3a21644
Merge pull request #1216 from cipherstash/feat/golang-operator-queries
coderdan Oct 17, 2026
6ddcaf2
feat(eql-bindings): produce IntegerEq, BigintEq, RealEq and DoubleEq,…
coderdan Oct 17, 2026
7f8cb75
test(golang): the guest's own catalog tests list the four number equa…
coderdan Oct 17, 2026
7c8e018
refactor(eql-bindings): compile eql_bindings::v4 only with the stack-…
coderdan Oct 17, 2026
2c53bea
fix(deps): take chacha20 0.10.2, since 0.10.0 and 0.10.1 were yanked
coderdan Oct 18, 2026
40c39a2
refactor(eql-bindings): take the Rust primitives as the v4 number and…
coderdan Oct 18, 2026
863240d
test(eql-bindings): check the v4 inventory against the catalog, not a…
coderdan Oct 18, 2026
d5e660d
Merge pull request #1241 from cipherstash/feat/eql-v4-equality-types
coderdan Oct 18, 2026
2a76ae2
feat(stack-encrypt)!: hold a dynamic plaintext as its frame, not a va…
coderdan Oct 17, 2026
1bcdb30
docs(adr): amend ADR-0002 for frames; name the residual decrypt copy'…
coderdan Oct 17, 2026
65c5962
test(stack-encrypt): pin ValueFrame::into_inner; name one equivalent …
coderdan Oct 17, 2026
e0c425f
fix(eql-bindings): wipe the opened text an EQL target decrypt frames
coderdan Oct 17, 2026
52835c3
test(stack-encrypt): fail on any freed heap block that still holds pl…
coderdan Oct 17, 2026
ce43bd7
docs(stack-encrypt): control data carries credentials; name the stack…
coderdan Oct 17, 2026
7880bd1
fix(stack-encrypt): refuse an out-of-model value in a passthrough as …
coderdan Oct 17, 2026
7382dad
perf(stack-encrypt,golang): check a record source in place instead of…
coderdan Oct 17, 2026
9e4f2a9
test(stack-encrypt,eql): match the excluded aws-lc seal frame on ever…
coderdan Oct 17, 2026
b38fbe5
fix(stack-encrypt): refuse a repeated key in a passthrough as Repeate…
coderdan Oct 18, 2026
cfa84f3
test(stack-encrypt,eql): scan freed blocks with memmem; grow a buffer…
coderdan Oct 18, 2026
3241932
refactor(stack-encrypt): derive OpaqueDebug for ValueFrame, and docum…
coderdan Oct 18, 2026
8dd8f32
docs: FfiValue goes, the kinds question is settled, and the decrypt r…
coderdan Oct 18, 2026
f65e3d0
feat(stack-encrypt,golang): add the #1144 value kinds as vitaminc leaves
coderdan Oct 17, 2026
6906b69
feat(golang): take any built-in integer into an EQL integer type, ran…
coderdan Oct 17, 2026
2287d8a
docs(stack-encrypt,golang): document the #1144 value kinds
coderdan Oct 17, 2026
ca8ed7f
test(stack-encrypt): pin the u8 OPE term; name one equivalent mutant
coderdan Oct 17, 2026
b28558e
fix(golang): clear golangci-lint; drop an unreachable arm and an unus…
coderdan Oct 17, 2026
4c5d99e
test(golang): hold every term of a Go-sealed value-kinds record to Ru…
coderdan Oct 17, 2026
1bcb895
fix(golang): name the field when a date, decimal or timestamp is refused
coderdan Oct 17, 2026
56dfb8c
docs(golang): the zero Date, a zero decimal's sign, and which indexes…
coderdan Oct 17, 2026
30384e2
docs(adr): ADR-0002 on Go's integer kinds for index fields, and leap …
coderdan Oct 17, 2026
468501d
fix(stack-encrypt): read a field-type refusal with the right article
coderdan Oct 17, 2026
347a2e8
fix(golang): build the gensupport tests on 386, and keep Biome off th…
coderdan Oct 17, 2026
bee78c6
fix(golang): keep a self-encoding integer's EncryptValue, and convert…
coderdan Oct 18, 2026
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
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
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
a05affa
Merge pull request #1280 from cipherstash/feat/eql-v4-block-ore
coderdan Oct 19, 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
  •  
  •  
  •  
27 changes: 27 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,28 @@ 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 has no kind: `KindOf::passthrough` returns `Ok(None)`,
# which is `Ok(Default::default())`. `a_frame_names_its_kind` asserts it.
'stack-encrypt/src/dynamic/value_frame\.rs:\d+:\d+: replace <impl Sink for KindOf>::passthrough -> 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\(\)\)$',
]

# 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-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.
2 changes: 1 addition & 1 deletion .changeset/eql-plan-field-targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
'@cipherstash/eql': minor
---

**The `eql-bindings` crate resolves an EQL type named as a string to its own Stack Encrypt plan** (`stack-encrypt` feature). `eql_bindings::encryption::targets` carries a catalog-generated table of every EQL type a data plan may name as a field target — its name across languages, family and suffix, the plaintext `ValueKind` it takes, the indexes it carries, its query twin, and whether the engine can produce it today with the reason when not — and `encrypt` / `decrypt` / `query` entry points that dispatch on the name and run the type's derived `EncryptFrom` / `DecryptInto`, resolving to the EQL value's JSON bytes through the engine's `Pending` so a guest batches it with the rest of a plan. This is the EQL half of EQL types as plan field targets (cipherstash/stack#1062): a Go data plan names `TextEq` and the guest returns the finished EQL value instead of assembling one. `TextEq` is the only producible type; every other name is refused with the plan's reason. The SQL surface and the TypeScript package are unchanged.
**The `eql-bindings` crate resolves an EQL type named as a string to its own Stack Encrypt plan** (`targets` feature, which turns on `stack-encrypt`). `eql_bindings::encryption::targets` carries a catalog-generated table of every EQL type a data plan may name as a field target — its name across languages, family and suffix, the plaintext `ValueKind` it takes, the indexes it carries, its query twin, and whether the engine can produce it today with the reason when not — and `encrypt` / `decrypt` / `query` entry points that dispatch on the name and run the type's derived `EncryptFrom` / `DecryptInto`, resolving to the EQL value's JSON bytes through the engine's `Pending` so a guest batches it with the rest of a plan. This is the EQL half of EQL types as plan field targets (cipherstash/stack#1062): a Go data plan names `TextEq` and the guest returns the finished EQL value instead of assembling one. Every target is an `eql_v4_*` domain. `TextEq` is the only producible type; every other name is refused with the plan's reason. The SQL surface and the TypeScript package are unchanged.
5 changes: 5 additions & 0 deletions .changeset/eql-target-match-options.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cipherstash/eql': minor
---

**`eql-bindings` says which match options an EQL type's filter is built under** (`targets` feature). `Target::match_options()` returns `EqlMatch`'s options for a type with a match index (`TextMatch`) and `None` otherwise, so Stack Encrypt can answer `matches` through the type's query twin: it cuts the query's tokens for `verify` exactly as the stored filter was cut. The SQL surface and the TypeScript package are unchanged.
2 changes: 1 addition & 1 deletion .changeset/eql-text-equality-transcoding.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
'@cipherstash/eql': minor
---

**Rust `TextEq` and `TextEqQuery` support Stack Encrypt's target-directed API behind the `stack-encrypt` feature.** The stored table and column identifier supplies the encryption context; native ciphertext and equality terms are transcoded into EQL payloads while Vitamin C owns plaintext encoding. This is a new producer profile with exact string equality, independent of existing cipherstash-client ciphertext and terms. Query operands carry no recoverable ciphertext.
**Rust `eql_bindings::v4::text::{TextEq, TextEqQuery}` support Stack Encrypt's target-directed API behind the `stack-encrypt` feature.** Stack Encrypt writes EQL v4 only, so the `eql_v3` types carry no Stack Encrypt traits. The stored table and column identifier supplies the encryption context; native ciphertext and equality terms are transcoded into EQL payloads while Vitamin C owns plaintext encoding. This is a new producer profile whose string equality compares text in Unicode 16 NFC without folding case, independent of existing cipherstash-client ciphertext and terms. Text holding a code point unassigned in Unicode 16 is refused, when it is stored as well as when it is queried. Query operands carry no recoverable ciphertext.
9 changes: 9 additions & 0 deletions .changeset/eql-v4-bindings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@cipherstash/eql': minor
---

**The `eql-bindings` crate has an `eql_bindings::v4` module, with the `stack-encrypt` feature: 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, so the module exists only with that feature and its types derive Stack Encrypt's traits without a further gate. The module is generated from the same catalog as `v3`, with `eql_v4_*` domain names and `"v": 4`. `SchemaVersion` is now generic over the version it admits: `v3::SchemaVersion` is `SchemaVersion<3>` and `v4::SchemaVersion` is `SchemaVersion<4>`, each refusing the other's payloads, and plain `SchemaVersion` still means v3. Only v4 types derive Stack Encrypt's `EncryptFrom` and `DecryptInto`, and the Stack Encrypt target table (now `eql_bindings::v4::targets`) names v4 domains. Besides `TextEq`, Stack Encrypt now produces the storage-only types `Text`, `Integer`, `Bigint`, `Boolean`, `Real` and `Double`, and `TextMatch` (3-grams, `k = 6`, a 2048-bit filter, pinned as `eql_bindings::encryption::EqlMatch`; text shorter than three characters is refused, stored or queried, and only `stored @@ query` matches until #1171 is fixed), from the Rust primitives `i32`, `i64`, `bool`, `f32` and `f64`; the Go SDK's `encrypt/eql` table marks them producible. Stack Encrypt also produces the number equality types `IntegerEq`, `BigintEq`, `RealEq` and `DoubleEq`, whose `=` compares as PostgreSQL compares the plain types: an integer has one term whatever its width, and for floats `-0.0 = 0.0` and `NaN = NaN` (ADR-0002's semantic baseline). Every type it cannot produce yet names the issue that tracks its blocker. A Rust caller queries those types through Stack Encrypt's typed query chain: `cipher.query(op::Eq, v).on(&plan)` on a plan for `TextEq` or a number equality type returns the type's query twin, and `cipher.query(op::Matches, text).on(&plan)` on a plan for `TextMatch` returns a `MatchTwin<TextMatchQuery>` with `verify` and `target_limit`, the same bytes and answers as the data path the Go SDK uses (`eql_bindings::encryption::query`; an operator a type does not answer does not compile). The by-name target entry points (`eql_bindings::encryption::targets::encrypt`, `decrypt` and `query`) exchange the plaintext as Stack Encrypt's `dynamic::ValueFrame`, one value as its transport frame, rather than a value tree. They, and the generated `v4::targets` table, need the new `targets` feature, which turns on `stack-encrypt` and Stack Encrypt's `dynamic` feature. `stack-encrypt` alone no longer builds Stack Encrypt's `dynamic` layer, so a Rust program using the typed v4 types through `encrypt_as` doesn't compile it.

**The EQL v4 SQL bundle has range query domains and `eql_v4.between`, so a `BETWEEN` query is one operand.** The v4 bundle (`cipherstash-encrypt-v4.sql`) is built from this source and reaches users as the `eql-v4-install.sql` attached to each Go release; neither the npm package nor the crate ships it, and the v3 SQL they ship does not change. Every ordered family has one range query domain per order term, beside its single-bound ones: `eql_v4.query_integer_range_ore` beside `eql_v4.query_integer_ord_ore`, `eql_v4.query_integer_range_ope` beside `eql_v4.query_integer_ord_ope`, and the same for `smallint`, `bigint`, `date`, `timestamp`, `numeric`, `text`, `real` and `double`. A range is `{"v": 4, "i": …, "lo": <term>, "hi": <term>}`: each bound is the single-bound domain's `ob` (ORE) or `op` (OPE) value, in a `{v, i, lo, hi}` envelope. Stack Encrypt does not build that envelope yet; it will need to when the ordered types become producible. `eql_v4.between(column, range)` is true when the column's order term lies between the bounds, both included, and has an overload for every ordered column domain with the range of the term it stores (`_ord_ore` and `_search_ore` take the ORE range; `_ord`, `_ord_ope` and `_search` the OPE one). It is an inlinable SQL function, so a btree on the column's order term (`eql_v4.ord_term_ore(col)` or `eql_v4.ord_term(col)`) serves it as one index range scan. Write it schema-qualified (`BETWEEN` is an SQL keyword, so a bare `between(...)` does not parse), and cast the range to its exact domain (`$1::eql_v4.query_integer_range_ore`): an uncast `$1`, a `jsonb` parameter, or a range of another term or family fails with SQLSTATE 42725 ("function … is not unique"), unlike the single-bound operators, which resolve an untyped `$1`. An ORE range scan needs the `ore_block_256` btree operator class, which the installer creates only as a superuser; on an install without it (Supabase and other non-superuser roles), the ORE range domains are disabled like the single-bound ORE domains, and a value cast to one raises `feature_not_supported` naming the family's OPE range. In the crate, `eql_bindings::v4` (`stack-encrypt` feature) has a type for each range domain (`IntegerRangeOreQuery`, `TextRangeOpeQuery`, …, listed by `v4::all_range_query()`). EQL v3 has no range domains: its SQL and types are unchanged (ADR-0009, decision 7).

Nothing a released version shipped has changed. The v3 types, the v3 SQL and the TypeScript package are as they were; the `stack-encrypt` derives on the v3 text types and the `v3::targets` module were added after the last release and are moved to v4 here, not removed from a release.
5 changes: 5 additions & 0 deletions .changeset/eql-v4-block-ore-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cipherstash/eql': minor
---

**EQL v4 compares ore-rs's 6-bit block ORE, and Stack Encrypt produces the block ORE types `IntegerOrdOre`, `SmallintOrdOre`, `BigintOrdOre`, `RealOrdOre`, `DoubleOrdOre`, `TextOrdOre` and `TextSearchOre`.** A v4 `ob` term is one ore-rs ciphertext: the fixed-width scheme for numbers, the chained scheme for text (padded to a power-of-two length bucket of at least 16 bytes). The v4 bundle names its block ORE objects `ore_block_v2` (`eql_v4_internal.ore_block_v2_term`, `compare_ore_block_v2_term`) and compares them with a new comparator that checks each term's shape, raises on malformed or mismatched terms, and runs a constant operation count for terms of one shape. The EQL v3 bundle is unchanged, byte for byte: its `ob` is still cipherstash-client's 8-bit block ORE under `ore_block_256`. See [U-002](../../docs/upgrading/v3.1.md#u-002-the-block-ore-term-is-ore-rss-6-bit-scheme): the comparator refuses the 8-bit terms the previous `eql_v4` bundle compared, so rows or operands holding them must be written again through Stack Encrypt.
5 changes: 5 additions & 0 deletions .changeset/eql-v4-date-timestamp-numeric.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cipherstash/eql': minor
---

**Stack Encrypt produces the EQL v4 date, timestamp and numeric types `Date`, `DateEq`, `Timestamp`, `TimestampEq`, `Numeric` and `NumericEq`** (`eql-bindings`, `stack-encrypt` feature). Their Rust plaintexts are the crate's own `v4::plaintext::Date`, `Timestamp` and `Decimal`, which hold the integers the engine stores (days since 1970-01-01; Unix seconds and nanoseconds; a mantissa and a scale), are range checked when built and are wiped when dropped. The `chrono` and `rust_decimal` features convert to and from those crates' types. `=` on `NumericEq` normalises the scale (`1.5 = 1.50`) and on `TimestampEq` compares to the microsecond, truncating (never rounding) the nanoseconds below it; each value decrypts as it was stored. The ordered types of these families stay unproducible until the engine derives their order terms. The Go SDK's `encrypt/eql` table marks the six producible, from `encrypt.Date`, `time.Time` and `encrypt.Decimal`.
5 changes: 5 additions & 0 deletions .changeset/eql-v4-ordered-ope-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cipherstash/eql': minor
---

**Stack Encrypt produces the OPE-ordered EQL v4 types `IntegerOrd`, `SmallintOrd`, `BigintOrd`, `RealOrd`, `DoubleOrd`, `TextOrd` and their `OrdOpe` twins** (`eql-bindings`, `stack-encrypt` feature). Their `op` term orders by ADR-0002's order key, so `<`, `<=`, `>`, `>=` and `ORDER BY eql_v4.ord_term(col)` compare integers by value, floats as PostgreSQL's `float8` does and text by its fold (case and accents folded). `=` on text reads `TextEq`'s equality term. `TextSearch` stays unproducible, with a reason: its query carries a match term that short text cannot make.
5 changes: 5 additions & 0 deletions .changeset/eql-v4-smallint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cipherstash/eql': minor
---

**Stack Encrypt produces the EQL v4 types `Smallint` and `SmallintEq`** (`eql-bindings`, `stack-encrypt` feature), from `i16`. `SmallintEq`'s equality term is the integer one, so a smallint and an integer of the same value under one column share it. The `date`, `timestamp` and `numeric` types now say they wait for a choice of Rust plaintext type, not for an engine kind.
5 changes: 5 additions & 0 deletions .changeset/eql-v4-text-search-optional-terms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cipherstash/eql': minor
---

**An EQL v4 text search query carries only the terms its operator reads.** `eql_v4.query_text_search` and `eql_v4.query_text_search_ore` now require at least one of their terms (`hm`, `op` or `ob`, `bf`) instead of all of them, so `col = $1` and `col < $1` work on text too short to cut a 3-gram, which has no match term. Each extractor over such a query raises (`invalid_parameter_value`) wherever it reads the operand when the query lacks the term it reads, or holds it as JSON `null` or an empty array, naming the domain, the term and the operators that compare it: `=` without `hm`, `<` without `op`, `@@` without `bf`. So a missing term raises rather than matching no row silently, or every row; the raise is at evaluation, so a generic plan that never reaches the predicate returns no row and no error. Stored `eql_v4_text_search` values still carry every term. The `eql_v3` domains are unchanged: the v3 bundle is byte for byte what it was. With it, **Stack Encrypt produces `TextSearch`** (`eql-bindings`, `stack-encrypt` feature): `TextSearchQuery`'s terms are `Option`s, built per index through `TextSearchEqualityQuery`, `TextSearchOrderQuery` and `TextSearchMatchQuery`, and the stored value carries every term: text too short for a 3-gram stores the empty filter (`"bf": []`, the new `v4::terms::SearchBloomFilter` field type), so `=` and `<` find it and no `@@` query does, where `TextMatch` still refuses it. `TextSearchQuery`'s `Option` terms and `TextSearch`'s `SearchBloomFilter` change the fields of the unreleased `v4` module only; no published `eql-bindings` has it. See [U-001](../../docs/upgrading/v3.1.md#u-001-a-text-search-query-carries-only-the-terms-its-operator-reads) for what a hand-built query must carry, the raise, and the rollback.
20 changes: 20 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copilot instructions for cipherstash/stack

The project instructions are in `AGENTS.md`. When reviewing a pull request,
follow its "Review guidelines", in particular these known non-findings,
which are deliberate design decisions and not defects:

- A sealed container's membership, order and length are not authenticated:
which entries a stored map holds, and a stored sequence's order, length
and duplicates, are not bound into any AAD, because stored values are
database rows and columns that come back in any order and in part. A
target that refuses a container's shape is a shape mismatch
(`Error::OpenedType`), not tampering (`Error::Aead`).
- A passthrough field is stored in the clear and is not authenticated,
except a plan's context field, which every other field is sealed under.
- Two leaves sealed under the same context are interchangeable between rows;
binding a value to its row is the caller's choice of context.

A leaf that is not bound to its context, map key, role (single value or
sequence element), type tag or wire version is still a defect. See
`packages/stack-encrypt/docs/adr/0010-what-a-stored-value-authenticates.md`.
Loading
Loading