Repository navigation
stash eql migration: migration-first, ORM-agnostic EQL v3 install (fixes prisma-next superuser-on-Supabase) #690
Copy link
Copy link
Closed
Labels
Description
Problem
EQL install differs per integration, and prisma-next's approach breaks on Supabase:
- Drizzle (v3) delegates EQL install to the CLI (
stash eql install), which owns four pre-built SQL variants + runtime Supabase selection + grants. Works everywhere. - prisma-next owns install by inlining the full v2 bundle into a baked baseline migration (
migrations/…/ops.json→installBundleop). That bundle has 9CREATE OPERATOR CLASS/FAMILYstatements → requires superuser → fails on Supabase (Supabase'spostgresrole is not a superuser). It also applies no grants and has no target awareness (the descriptor is static, so there's no apply-time "is this Supabase?" seam).
Root cause confirmed by reproducing the bundle diff: the CLI's cipherstash-encrypt.sql has 9 operator classes/families; cipherstash-encrypt-supabase.sql has 0 (that's the only difference, ~210 lines). The CLI picks the right one at install time via resolveBundledFilename.
Decisions (owner: @coderdan)
- prisma-next is v3-only. v2 was never released for prisma-next, so drop it entirely. Both Drizzle and prisma-next migrations target EQL v3. (prisma-next's move to v3 is PR Feat/prisma next eql v3 #655, in-flight.)
- Migration-first, ORM-agnostic install via a new CLI command:
stash eql migration --drizzle | --prisma [--supabase] [--out <dir>] [--name <name>] [--dry-run]- Emits an EQL-install migration file in the target ORM's format (preferred over direct-to-DB execution, which stays as
stash eql installfor quick/dev). - Single source of install SQL: the CLI's bundled v3 SQL (
loadBundledEqlSql({ eqlVersion: 3 })).--supabaseappends the v3 grants (supabaseGrantsFor(3)→eql_v3+eql_v3_internalGRANTs to anon/authenticated/service_role). (The v3 bundle itself is a single file used for all targets — its operator classes do not trip the superuser wall the way v2's 9 do.) --drizzle→ reuse the existing Drizzle custom-migration emission.--prisma→ new emitter writing a Prisma-Nextmigration.ts(the frameworkMigrationshape) into the user's migrations dir.
- Emits an EQL-install migration file in the target ORM's format (preferred over direct-to-DB execution, which stays as
- prisma-next stops owning install. Its baked-in
installBundlebaseline (the inlined bundle inops.json) is removed; users generate the install migration withstash eql migration --prisma [--supabase], exactly as Drizzle users would. This is the change that makes prisma-next Supabase-safe.
Sequencing (3 PRs)
- PR1 —
stash eql migration --drizzle [--supabase](v3), offmain. Independent of prisma-next; Drizzle v3 is already on main. Adds theeql migrationcommand (registry + dispatch + generation), reusingloadBundledEqlSql/supabaseGrantsFor.--prismais registered but returns "not yet available (tracked here)" until PR3. Tests +stash/stash-drizzle/stash-cliupdates + changeset. Merge this. - PR2 — rebase Feat/prisma next eql v3 #655 (
feat/prisma-next-eql-v3) on the merged PR1. - PR3 —
--prismaemitter + remove prisma-next's baked baseline, stacked on Feat/prisma next eql v3 #655. Emits the v3 install migration in the frameworkMigrationshape; drops theinstallBundleop from the descriptor/ops.json; updates the prisma-next skill/example to runstash eql migration --prisma.
Notes
- Grants: Drizzle/prisma-next apps connect directly as
postgres, so the anon/authenticated/service_role grants matter only when the same tables are also reached via PostgREST/RLS.--supabaseincludes them for parity withstash eql install --supabase; harmless (idempotent) otherwise. - This unifies EQL-install SQL under one CLI source of truth (no vendored fork per ORM), which also removes prisma-next's "indivisible bundle" maintenance burden.
Part of the stack 1.0 + EQL v3 GA push.
Reactions are currently unavailable
Activity
coderdan commentedon Jul 17, 2026
PR1 is up: #691 (
stash eql migration --drizzle, off main). Once merged → rebase #655 → PR3 adds--prisma+ removes prisma-next's baked baseline, stacked on #655.coderdan commentedon Jul 17, 2026
PR2 done + PR3 (
--prismaemitter) designPR2 — rebase complete. #655 (
feat/prisma-next-eql-v3) rebased onto #691. Old tip06df3474→ newb6ff7c43, force-pushed with lease, zero content conflicts (691 is CLI-only; 655 is prisma-next). Verified on the rebased tip: builds clean, prisma-next 599 unit pass, cli 557 pass. PR3 branchfeat/eql-migration-prismais off it.Finding that resizes PR3: #655 ships two baked baseline migrations, both wired in
control.ts— the v2installBundleand a new v3installBundleV3(migrations/20260601T0100_install_eql_v3_bundle, sourcing@cipherstash/eql/sqlreadInstallSql()). So "remove the baked baseline" = remove both and rework the contract-space head-ref/invariants that carry them. That's delicate surgery on the model #655 just built (CJ's domain).Emitter design fork (need a call): the emitted prisma-next migration must carry the v3 install SQL, but prisma-next's public
./migrationexport only exposescipherstashAddSearchConfig— not the install SQL (it's baked from a devDependency,@cipherstash/eql/sql, on purpose). Two ways:loadBundledEqlSql({eqlVersion:3})— already in feat(cli): addstash eql migration --drizzle(v3, migration-first EQL install) #691) into the emitted migration. Keeps one source of truth; needs the emitted artefact to be a frameworkmigration.ts+ emittedops.json(viaMigrationCLI.run) or a directly-writtenops.json. Caveat: reconcile the CLI'scipherstash-encrypt-v3.sqlvs prisma-next's@cipherstash/eql/sql— they must be the same eql release.Recommend A. Open question is the emit format (write
migration.tsand have the user run the framework emit, vs. the CLI producingops.jsondirectly) and the SQL-version reconciliation — both touch CJ's contract tooling, so worth a quick sync with him before the removal half.feat(cli): add `stash eql migration --drizzle` (v3, migration-first E…
docs(cli): correct `--prisma` copy to match #690 (planned emitter, no…
feat(cli): add `stash eql migration --drizzle` (v3, migration-first E…
fix(cli): eql migration --prisma is 'not needed', not 'not yet'
fix(cli): eql migration --prisma is 'not needed', not 'not yet'
chore(cli): sweep stale '#690 emitter pending' comments; rename migra…
feat(skills): stash-zerokms and stash-auth — canonical keyset and aut…