Repository navigation
Description
Background
Stack Encrypt (packages/stack-encrypt) is the Rust engine that every CipherStash language SDK runs on. It is published on crates.io. Vitamin C is our separate library of cryptographic primitives, formats, and encodings.
The Stack Encrypt API plan, merged in pull request #1365, ran a naming review on 8 November 2026. Every public name it covered is now decided. The packaging document proposes a crate for each trait and format. That proposal is not yet approved.
Problem
The names in code on next are still the old ones. The renames are breaking changes, so they should land together, once, before the stable release. The crate boundaries are still open, and moving a crate after release is harder.
Proposal
Part 1: apply the naming review
The plan's names table lists each decision. In short:
StackCipherbecomesCipher, andKeysetCipherbecomesKeyset.- In Go,
ClientbecomesCipher, withNewCipher, and the keyset-boundCipherbecomesKeyset. Generated_stash.gofiles must be generated again once. OpSpecbecomesOp.#[stash(context = "..")]becomesscope = "..",Plan::context(..)becomesPlan::scope(..), and Go'scontext=tag becomesscope=.- The marker trait
op::QueryTermbecomesQuery, andLabelledTargetbecomesStored. Thedynamic::QueryTermstruct keeps its name. - The ZeroKMS unit of work
Requestbecomes crate-private. A binding sends a serialisedPlanorPlannedinstead. ContextExtensionis removed.EncryptionPlanis never added.
CipherScope, dynamic::Scope, Label, and IntoLabel are removed as part of #1488.
None of these changes the stored format.
Part 2: decide the packaging
These questions are still open:
- Should
stack-kmsbe renamedstack-zerokms? - Which Vitamin C crate should contain
Base64TextandBase85Text? The plan decided they move to Vitamin C. - Should
AsyncCipherbe retired, as the packaging document proposes? - How should the leaf cipher be split into sealing and opening? Today two types each implement half of Vitamin C's
Ciphertrait. Each returns an error from the other half. - How does this fit the index crate split in stack-encrypt: every index is compiled into the core crate — move
Equality,Match,Ore,Opeinto their own crates #1063? Do not create a second, competing split.
Acceptance
- No old name remains in the public Rust or Go API.
- The examples in the plan's Target state compile under the new names.
- The packaging document's glossary matches the code.
- Each Part 2 question has a recorded decision.
- The dependency graph between Stack Encrypt, EQL, and Vitamin C has no cycle.
- Builds without HTTP and for WASM still work. SQL and engine interoperability are unchanged.
- Rust, EQL, and binding consumers are updated in a coordinated release, and conformance and artifact exchange pass again.
Relationship to other work
- Go SDK: methods on Cipher and Client take a *record.Plan and their docs and errors say "plan" — rename and hide them #1116 and Go: public plan-building API for types stashgen can't tag (reconcile with #1116) #1307 cover the Go plan names and a public Go plan builder.
- Pull request feat(stack-encrypt)!: derive owned record declarations with EncryptTarget and DecryptSource #1504 adds
context = ".."andContextExtension. This issue removes both. See stack-encrypt refactor: migrate record derives and plans to owned declarations #1483. - Sequence after stack-encrypt refactor: remove transitional traits and redundant execution APIs #1488, unless a specific dependency needs a crate move first.
Plans: the Stack Encrypt API plan and the conformance roadmap.
Activity