Updated 2026-10-05 (PDT). The Go SDK design is PR cipherstash/stack#1070: docs/plans/2026-10-04-plan-builder.md, "The Go SDK", and the principles in docs/sdk-design-principles.md (ADR-0008). The declaration is a tag, stash:"attrs,index=json", with options in parentheses after the name. stashgen writes one query method on the field entry for each JSON query form. There is no Json() constructor and no plantest. The JSON index itself is a new engine operation, and the generator refuses index=json until the engine has it.
Background
The Go binding (languages/golang/stackencrypt/) runs stack-encrypt, our Rust field-level encryption library, inside a WebAssembly guest. #1046 reshapes it into one chained Encrypt that takes a plan: per field, a context and the search indexes to derive. #1060 adds a JSON index to stack-encrypt, so a JSON document field can be queried by containment, by path, and by value at a path.
Problem
Once the Rust JSON index exists, Go has no way to name it in a plan or to ask the three JSON query forms. Go cannot pick a query form from a static source type the way Rust does, so the forms need an explicit Go spelling.
Proposal
From docs/plans/2026-10-04-plan-builder.md (PR cipherstash/stack#1052), "The Go mirror". Exact signatures belong in the PR.
stackencrypt.Json() as an index, used as Index("attrs", stackencrypt.Json()) in a chain or saved plan, with its options (array index mode, Compat/Standard, case filters) as Go options on the constructor.
Query(..).Using(attrsPlan) with the form chosen by the source value's Go type: a document value for containment, a path value for a selector, a path-with-value for equality at a path.
- Decrypting an extracted entry works through the same
Decrypt(..).Using(..) call.
- Live tests and
plantest.Golden snapshots cover all three forms.
Relationship to other work
Background
The Go binding (
languages/golang/stackencrypt/) runs stack-encrypt, our Rust field-level encryption library, inside a WebAssembly guest. #1046 reshapes it into one chainedEncryptthat takes a plan: per field, a context and the search indexes to derive. #1060 adds a JSON index to stack-encrypt, so a JSON document field can be queried by containment, by path, and by value at a path.Problem
Once the Rust JSON index exists, Go has no way to name it in a plan or to ask the three JSON query forms. Go cannot pick a query form from a static source type the way Rust does, so the forms need an explicit Go spelling.
Proposal
From
docs/plans/2026-10-04-plan-builder.md(PR cipherstash/stack#1052), "The Go mirror". Exact signatures belong in the PR.stackencrypt.Json()as an index, used asIndex("attrs", stackencrypt.Json())in a chain or saved plan, with its options (array index mode,Compat/Standard, case filters) as Go options on the constructor.Query(..).Using(attrsPlan)with the form chosen by the source value's Go type: a document value for containment, a path value for a selector, a path-with-value for equality at a path.Decrypt(..).Using(..)call.plantest.Goldensnapshots cover all three forms.Relationship to other work
docs/plans/2026-10-04-plan-builder.mdon PR cipherstash/stack#1052.