Part of #707 (EQL v2 removal). Once v2 is gone, the *V3 suffix is redundant — v3 should take the unsuffixed name across the adapter packages. The decision is already made in #707's "Naming — decided" section: v3 takes the unsuffixed name; the *V3 name stays as a @deprecated alias (except Drizzle — see below). This issue tracks executing that decision.
Why a separate issue
- The aliases are not for v2 users (they're gone at that version) — they exist so people who already migrated to v3 don't rewrite every import a second time for zero functional gain. This is a naming cleanup the removal enables, not part of any deletion.
- It has a consumer grep won't flag — the
stash init scaffold emits encryption symbols as generated strings (see cli item below), so a call-site search misses it.
- It has one hard-break exception (Drizzle) that must not be aliased.
Hard sequencing constraint
De-suffixing a package must follow that package's own v2 removal — v3 cannot claim the unsuffixed name while v2 still holds it (name collision). So this is the closing step of each adapter's removal, done per-package right after that package's v2 is deleted/refactored. It is independent of the prisma-next stack, #751, and #725 (they touch none of these symbols).
Per-package work
prisma-next — already done, no work
4923c0a already gave v3 the unsuffixed names (cipherstashFromStack at src/exports/stack.ts:44, v2 is cipherstashFromStackV2 at :34). Its *V2 symbols are deleted outright by the prisma-next removal, no alias. Nothing to do here.
stack-supabase — safe alias, do it
encryptedSupabaseV3 (src/index.ts:133, overloaded) → encryptedSupabase, with encryptedSupabaseV3 kept as a @deprecated alias. Safe because the v2 and v3 signatures are incompatible in every dimension (sync 1-arg config object vs async 2–3-arg string | SupabaseClientLike first), so a stale v2 call fails loudly rather than silently rebinding (#707 Naming §Supabase). Same treatment for the ~14 *V3 type exports (EncryptedSupabaseV3Options, V3FilterableKeys, TypedEncryptedSupabaseV3Instance, …).
stack-drizzle — HARD BREAK, no alias
The ./v3 subpath (package.json:46) collapses to the root. Post-collapse the root names — createEncryptionOperators (src/operators.ts:985), extractEncryptionSchema — are the same names the v2 API uses today, and the two forms are similar enough that a stale import would keep type-checking while silently binding to v3 semantics. So the old path must be removed outright (no @deprecated alias) — a loud failure, not a silent rebind (#707 Naming §Drizzle). v3 sources: src/v3/index.ts (createEncryptionOperatorsV3, extractEncryptionSchemaV3).
stack — minimal
Encryption is generation-neutral and survives; EncryptionV3 is Encryption with eqlVersion: 3 pinned. Confirm the EncryptionV3 alias/wrapper story after v2 removal; likely a doc/@deprecated touch only.
cli init scaffold — flip the generated text
packages/cli/src/commands/init/utils.ts emits the client as generated strings, so a grep for call sites won't flag it. Note current source emits the unsuffixed v2 symbols — import { Encryption } from '@cipherstash/stack' (:309,343,408), encryptedType, extractEncryptionSchema from @cipherstash/stack-drizzle (:308,407), encryptedTable, encryptedColumn from @cipherstash/stack/schema (:342,443). This overlaps the "scaffold emits v2" defect (scope §4/§7). Reconcile both here: the emitted strings must name whatever the unsuffixed symbols mean after de-suffixing (v3). (Scope §Naming references #734 as having ported this to EncryptionV3; that is not what current source shows — verify the live scaffold output when this lands.)
Cross-cutting
- Changesets:
major for stack-supabase and stack-drizzle (breaking renames / hard break); patch/minor for stack and stash as touched.
- Skills: scrub
*V3 naming guidance in stash-supabase, stash-drizzle, stash-cli, stash-encryption (+ stash patch changeset — skills ship in the tarball).
- Meta: AGENTS.md Repository Layout / Key Concepts sections name several
*V3 symbols.
Done when
- Adapter public APIs present the unsuffixed name as canonical;
*V3 is a @deprecated alias everywhere except the Drizzle ./v3 collapse, which is a hard break.
- The cli scaffold emits the post-de-suffixing (v3) symbol names.
- Skills / AGENTS.md / changesets updated; build + typecheck + tests green across the touched packages.
Reference: #707 "Naming — decided"; docs/plans/2026-07-20-eql-v2-removal-scope.md §6 "Naming debt".
Part of #707 (EQL v2 removal). Once v2 is gone, the
*V3suffix is redundant — v3 should take the unsuffixed name across the adapter packages. The decision is already made in #707's "Naming — decided" section: v3 takes the unsuffixed name; the*V3name stays as a@deprecatedalias (except Drizzle — see below). This issue tracks executing that decision.Why a separate issue
stash initscaffold emits encryption symbols as generated strings (see cli item below), so a call-site search misses it.Hard sequencing constraint
De-suffixing a package must follow that package's own v2 removal — v3 cannot claim the unsuffixed name while v2 still holds it (name collision). So this is the closing step of each adapter's removal, done per-package right after that package's v2 is deleted/refactored. It is independent of the prisma-next stack, #751, and #725 (they touch none of these symbols).
Per-package work
prisma-next — already done, no work
4923c0a already gave v3 the unsuffixed names (
cipherstashFromStackatsrc/exports/stack.ts:44, v2 iscipherstashFromStackV2at:34). Its*V2symbols are deleted outright by the prisma-next removal, no alias. Nothing to do here.stack-supabase — safe alias, do it
encryptedSupabaseV3(src/index.ts:133, overloaded) →encryptedSupabase, withencryptedSupabaseV3kept as a@deprecatedalias. Safe because the v2 and v3 signatures are incompatible in every dimension (sync 1-arg config object vs async 2–3-argstring | SupabaseClientLikefirst), so a stale v2 call fails loudly rather than silently rebinding (#707 Naming §Supabase). Same treatment for the ~14*V3type exports (EncryptedSupabaseV3Options,V3FilterableKeys,TypedEncryptedSupabaseV3Instance, …).stack-drizzle — HARD BREAK, no alias
The
./v3subpath (package.json:46) collapses to the root. Post-collapse the root names —createEncryptionOperators(src/operators.ts:985),extractEncryptionSchema— are the same names the v2 API uses today, and the two forms are similar enough that a stale import would keep type-checking while silently binding to v3 semantics. So the old path must be removed outright (no@deprecatedalias) — a loud failure, not a silent rebind (#707 Naming §Drizzle). v3 sources:src/v3/index.ts(createEncryptionOperatorsV3,extractEncryptionSchemaV3).stack — minimal
Encryptionis generation-neutral and survives;EncryptionV3isEncryptionwitheqlVersion: 3pinned. Confirm theEncryptionV3alias/wrapper story after v2 removal; likely a doc/@deprecatedtouch only.cli init scaffold — flip the generated text
packages/cli/src/commands/init/utils.tsemits the client as generated strings, so a grep for call sites won't flag it. Note current source emits the unsuffixed v2 symbols —import { Encryption } from '@cipherstash/stack'(:309,343,408),encryptedType, extractEncryptionSchemafrom@cipherstash/stack-drizzle(:308,407),encryptedTable, encryptedColumnfrom@cipherstash/stack/schema(:342,443). This overlaps the "scaffold emits v2" defect (scope §4/§7). Reconcile both here: the emitted strings must name whatever the unsuffixed symbols mean after de-suffixing (v3). (Scope §Naming references #734 as having ported this toEncryptionV3; that is not what current source shows — verify the live scaffold output when this lands.)Cross-cutting
majorforstack-supabaseandstack-drizzle(breaking renames / hard break); patch/minor forstackandstashas touched.*V3naming guidance instash-supabase,stash-drizzle,stash-cli,stash-encryption(+stashpatch changeset — skills ship in the tarball).*V3symbols.Done when
*V3is a@deprecatedalias everywhere except the Drizzle./v3collapse, which is a hard break.Reference: #707 "Naming — decided";
docs/plans/2026-07-20-eql-v2-removal-scope.md§6 "Naming debt".