Version Packages - #938
Open
github-actions[bot] wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@cipherstash/stack-prisma@1.2.0
Minor Changes
ba37039: Move the bundled EQL v3 migrations to eql-3.0.5, which renames the SQL
function
eql_v3.ste_vec_containstoeql_v3.jsonb_document_contains.The blast radius is narrower than a renamed public function suggests. The
@>/<@operators onpublic.eql_v3_json_searchbehave exactly as before,and so do the two function-form entry points that exist for platforms without
operator support —
eql_v3.jsonb_contains(jsonb, jsonb)andeql_v3.jsonb_contained_by(jsonb, jsonb)are byte-identical to 3.0.4. Thoseare what a PostgREST caller invokes, so PostgREST callers on the documented
surface are not affected. The renamed function is the typed implementation
those operators dispatch into.
And the old name still works. eql-3.0.5 ships
eql_v3.ste_vec_containsasa deprecated delegating alias for both overloads, so hand-written SQL naming it
— an application query, a view, an RLS policy, or a per-function
GRANT EXECUTE ON FUNCTION eql_v3.ste_vec_contains(…)— keeps resolving. Thetyped overload stays inlinable, so a function-form query through the alias
still matches the same functional GIN index. Migrate to
jsonb_document_containswhen convenient; nothing forces it at upgrade time.Separately — and true of every EQL upgrade, not just this one: the install
bundle opens with
DROP SCHEMA IF EXISTS eql_v3 CASCADE, so applying it dropsevery object in
eql_v3/eql_v3_internaland everything that depended onthem. Encrypted data and column types are not affected — the storage
domains are
public.eql_v3_*, deliberately outside both dropped schemas, andtheir CHECK functions are re-created rather than dropped. What does not survive
is everything else pointing into the schema, which is two actions, neither of
them to do with the rename:
eql_v3/eql_v3_internalobject is gone. The schema-wide form EQL documents —GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA eql_v3 TO app_role— picks upboth the new name and the alias on its own.
ANALYZE. Indexes overeql_v3.eq_term(…)/ord_term/match_term/to_ste_vec_query(…)depend on the dropped schema and go with it. Nothing errors afterwards:
encrypted predicates keep working and silently fall back to sequential
scans. A migration runner will not redo an already-applied migration, so
this has to be a new one. The
stash-indexingskill documents themechanism ("These indexes do not survive an EQL reinstall or upgrade") and
the
EXPLAINcheck that confirms recovery; capturing and restoring themautomatically is tracked in
cipherstash/stack#918.
Any RLS policy, view, or constraint that calls an
eql_v3function is droppedby the same CASCADE and needs recreating too. The rename itself needs no
action — the alias makes it non-breaking.
Two artefacts carry the new bundle:
20260814T0000_upgrade_eql_v3_3_0_5, carrying theinvariant
cipherstash:upgrade-eql-v3-bundle-3.0.5-v1. Databases alreadyrunning an earlier bundle re-install through this edge on the next
prisma-next migration planfollowed byprisma-next migrate, exactly asthey did for 3.0.2 and 3.0.4.
migratealone is not enough — the seedphase that copies a new migration package into your repo runs only from
migration plan, so without it the 3.0.5 directory never reaches disk andmigrateis a silent no-op that leaves the database on the older bundle.20260601T0100_install_eql_v3_bundle, whosebaked bundle moves to 3.0.5 and which gains a fourth no-SQL carrier op for
the new invariant. Fresh databases therefore land on 3.0.5 from the single
all-additive genesis edge, keeping
db init(additive-only policy) working.Action required. The baseline's bytes — and so its
migrationHash— havechanged. If your project already has a
migrations/cipherstash/directorygenerated against
@cipherstash/stack-prisma@1.0.0or@1.1.0, delete thatdirectory and re-run
prisma-next migration plan(ormigrate); the 1.1.0Prisma Next 0.17 upgrade re-anchored the same artefacts, so a space vendored
against either release is stale here. The seed phase regenerates
it byte-identical to the shipped artefacts. Your database keeps its markers, so
already-applied invariants are not re-run — the only new work is the 3.0.5
upgrade edge.
If you skip the delete, nothing warns you: a vendored baseline is stale but
internally intact, so it passes every integrity check. On an existing database
the upgrade still applies correctly; on a fresh one,
db initrefuses withOperation cipherstash.upgrade-eql-v3-bundle-3.0.5 has class "data" which is not allowed by policy.— an error that names neither the directory nor theremedy. See "Upgrading from 1.0.0" in the package README.
Why the baseline was re-emitted rather than left frozen. These artefacts are
content-addressed and normally append-only: an EQL bump ships as a new upgrade
directory and published directories are never rewritten. That rule cannot be
followed here without a second
from: nullgenesis edge, because no upgradeedge can ever be walked by
db init— every upgrade edge is a self-edge, andthe integrity checker requires a self-edge to carry a
data-class op, whichdb init's additive-only policy refuses. A fresh database must thereforecollect every head-ref invariant from the genesis edge it walks. The
append-only alternative would duplicate the full ~2.6 MB bundle into a new
genesis edge on every EQL release, permanently; re-emitting was taken instead
while 1.0.0 was two weeks old with negligible adoption, and is a decision to be
re-argued on adoption numbers rather than repeated by default.
Patch Changes
4422d5c: Pin the packed
@cipherstash/eqldependency to an exact version, closing aroute by which an installed EQL bundle could drift ahead of the code built
against it.
Both packages declared
"@cipherstash/eql": "workspace:^"underdependencies. In this workspace that resolves in-tree either way, so nothingin development or CI could see a difference — but the two specifiers do not
pack the same. pnpm rewrites the protocol when it builds the tarball a customer
actually installs:
The caret is the problem.
@cipherstash/eqlis still published fromcipherstash/encrypt-query-languageuntil the publisher repoint, so a 3.0.x canreach npm without passing through this repository at all — and
^3.0.5acceptsit. A customer installing
stashor@cipherstash/stack-prismawould then getSQL that STORES and queries encrypted payloads at one version, while
@cipherstash/stack's v3 domain types (which EMIT those payloads) andstack-prisma's baked migrations stayed frozen at the version this repo builtand tested against. The two halves of EQL are released in lockstep precisely
because that skew does not fail at install or in CI — it fails in a database.
workspace:*is the only form that closes it. A literal"3.0.5"would be anexact pin too, but it is a registry pin:
pnpm run lint:eql-pinsrejects it,because resolving EQL from a registry rather than from this repo is the same
drift one layer up.
No API, behaviour or SQL changes. What changes is the dependency range in the
published tarballs, and only in the narrowing direction — the version resolved
today is the version that was already being resolved. Nothing needs to be done
on upgrade.
@cipherstash/stackdeclares the same dependency underdevDependenciesandis deliberately left alone: pnpm rewrites that range too, but no consumer of the
package ever resolves it.
c604028: Document the 1.0.0 → 3.0.5 upgrade in the package README: why
migrations/cipherstash/must be deleted and regenerated, what each Prisma Nextcommand does if it is not, and the exact
db initrefusal(
Operation cipherstash.upgrade-eql-v3-bundle-3.0.5 has class "data" which is not allowed by policy.) that a stale vendored directory produces on a freshdatabase.
The behaviour worth knowing regardless of version: only
prisma-next migration plancopies new migration packages into your repo. Runningmigrateordb initafter upgrading this package without planning first silently leavesthe database on the older EQL bundle — a stale vendored directory is internally
intact, so it passes every integrity check and nothing reports a problem.
Updated dependencies [e52d331]
stash@1.2.0
Patch Changes
801868d: Verify the EQL install SQL against its release digest before running it.
stash eql installreads the EQL v3 bundle from the resolved@cipherstash/eqlin yournode_modulesand executes it against yourdatabase. That read was a bare
readFileSync— nothing checked that the byteson disk were the bundle the resolved release actually ships. A corrupt,
partially-updated, or tampered package installed silently: the database ended
up carrying SQL the version it reports does not define, and the CLI printed
"EQL extensions installed."
The CLI now hashes the bundle and compares it to
installSqlSha256from therelease manifest that ships alongside it, and refuses on a mismatch. The
error names the expected digest, the actual digest, the resolved file path and
the EQL version, so the remedy is visible rather than inferred. Verification
happens before any database connection is opened, so a refusal means nothing
was attempted — not that something was rolled back.
The check covers all three paths that read the bundle:
stash eql install,the SQL embedded by
stash eql migration --drizzle/--supabase, and theexpected-surface baseline
stash eql verifycompares your database against.@cipherstash/stack-prismahas verified against this same digest since its v3migrations landed; this brings the CLI in line.
No healthy install is affected — the SQL and its manifest are produced by the
same build of
@cipherstash/eql, so a mismatch only ever means a brokendependency tree.
skills/stash-clidocuments the new pre-flight alongside the existingpost-install surface check, so an agent reading it does not report a digest
refusal as a failed install.
4422d5c: Pin the packed
@cipherstash/eqldependency to an exact version, closing aroute by which an installed EQL bundle could drift ahead of the code built
against it.
Both packages declared
"@cipherstash/eql": "workspace:^"underdependencies. In this workspace that resolves in-tree either way, so nothingin development or CI could see a difference — but the two specifiers do not
pack the same. pnpm rewrites the protocol when it builds the tarball a customer
actually installs:
The caret is the problem.
@cipherstash/eqlis still published fromcipherstash/encrypt-query-languageuntil the publisher repoint, so a 3.0.x canreach npm without passing through this repository at all — and
^3.0.5acceptsit. A customer installing
stashor@cipherstash/stack-prismawould then getSQL that STORES and queries encrypted payloads at one version, while
@cipherstash/stack's v3 domain types (which EMIT those payloads) andstack-prisma's baked migrations stayed frozen at the version this repo builtand tested against. The two halves of EQL are released in lockstep precisely
because that skew does not fail at install or in CI — it fails in a database.
workspace:*is the only form that closes it. A literal"3.0.5"would be anexact pin too, but it is a registry pin:
pnpm run lint:eql-pinsrejects it,because resolving EQL from a registry rather than from this repo is the same
drift one layer up.
No API, behaviour or SQL changes. What changes is the dependency range in the
published tarballs, and only in the narrowing direction — the version resolved
today is the version that was already being resolved. Nothing needs to be done
on upgrade.
@cipherstash/stackdeclares the same dependency underdevDependenciesandis deliberately left alone: pnpm rewrites that range too, but no consumer of the
package ever resolves it.
ad033df:
skills/stash-prismanow documents the re-plan step that follows an@cipherstash/stack-prismaupgrade:rm -rf migrations/cipherstash && npx prisma-next migration plan, why onlymigration planvendors new migrationpackages, and the exact
db initrefusal a stale vendored directory produces ona fresh database (
Operation cipherstash.upgrade-eql-v3-bundle-3.0.5 has class "data" which is not allowed by policy.).The package README already carried this; the skill did not — and the skill is
what ships inside the
stashtarball and gets copied into a user's.claude/skills/, so an agent driving the upgrade hit the refusal with no routeout of it.
packages/stack-prisma/test/v3/stale-vendored-space.test.tsnow pinsboth files to the planner's real message so they cannot drift apart again.
4422d5c: Correct two things the bundled agent skills were telling customers wrongly
about EQL.
skills/stash-postgrespointed at the wrong repository. EQL's source nowlives in
cipherstash/stackunderpackages/eql/, and that is where operatorgaps and domain-level bugs are filed; only publishing still happens from
cipherstash/encrypt-query-language, which the skill continues to say. Theskill also cited "the EQL skill" as a source of truth that "ships from
encrypt-query-languagealongside the bundle" — no such skill ships fromeither repository, so the reference is gone and the remaining three sources
(the generated types, the install SQL, and
SELECT eql_v3.version()) arerenumbered.
And it claimed the CLI pins an exact
@cipherstash/eqlversion, "so adatabase is only ever on one bundle." Neither half holds: the CLI depends on
the workspace package rather than a pinned literal, and a database is on
whatever bundle was last applied to it — the Prisma Next adapter installs and
upgrades the bundle through its own migrations without involving the CLI at
all. Replaced with the guarantee that does hold: one
stashrelease carriesone resolved bundle, and the database is the authority on which bundle it has.
skills/stash-prismahands out the functional-index recipe without saying anEQL upgrade destroys it. Installing a bundle begins with
DROP SCHEMA IF EXISTS eql_v3 CASCADE, which cascade-drops every index over aneql_v3.*extractor — the PSL expression indexes Prisma Next 0.17 introduced and any
rawSqlindex DDL alike; queries keep working and silently sequential-scan.Because an applied migration is never replayed, recovery is a NEW one: a PSL
expression index has to change its
name:(the physical name carries a contenthash of the expression, so re-declaring the same one plans no work), and a
rawSqlrecovery op needs a newid. Said where the recipe is given, pointingat
stash-indexingfor the mechanism and atcipherstash/stack#918 for
capturing and restoring them automatically.
ba37039: Update the bundled agent skills for eql-3.0.5.
skills/stash-supabasere-states the PostgREST query-domain limitations against 3.0.5 (unchanged in
substance — the typed
eql_v3.query_*operand requirement still stands), andskills/stash-postgresdrops one of the two places it claimed the CLI pins@cipherstash/eqlto an exact version — a claim that stopped being true whenEQL moved in-tree. The second copy goes in the same release, with the rest of
that skill's EQL source and issue pointers.
Updated dependencies [e52d331]
@cipherstash/eql@3.0.6
Patch Changes
repository,repository.directory, andbugs.urlatcipherstash/stackinstead of the archivedcipherstash/encrypt-query-language. Purely metadata — no behaviour change — but required before npm's trusted publishing (already repointed atcipherstash/stack) can accept a release: npm rejects a publish whose manifestrepository.urldoesn't match the publishing repository.@cipherstash/protect-ffi@0.32.1
Patch Changes
4422d5c: Compile
eql-bindingsfrom this repository rather than from crates.io.The native binding pinned
eql-bindings = "=3.0.2"from the registry. It nowresolves by path from
packages/eql/crates/eql-bindings, which ships at 3.0.5alongside the
@cipherstash/eqlSQL bundle.No behaviour change.
eql-bindingsis the Rust half of EQL — it EMITS theencrypted payloads that the SQL half STORES and queries — and its Rust source is
byte-identical across 3.0.2, 3.0.4 and 3.0.5 (
src/,bindings/andschema/compared directly). What 3.0.3 through 3.0.5 changed was SQL, carried on the
shared lockstep version number. So the payloads this binding produces are the
same bytes before and after; what moves is the version stamped on the crate
compiled into
index.node, from 3.0.2 to 3.0.5.Why it is worth a release anyway. A registry pin let the two halves of EQL
drift apart silently. Nothing asserted they agreed: a mismatched pair compiles,
passes every suite, and fails in a database — because the failure is a payload
the installed SQL cannot read, which no unit test holds both sides of. Resolving
from the tree makes the skew unrepresentable: the emitter and the SQL are now
the same commit, and
pnpm run lint:eql-pinsfails any change that reintroducesa registry pin on either.
The flip was taken while it was a no-op deliberately. Waiting for the first
release where the two halves genuinely diverge would have turned a provenance
change into a behaviour change that had to be argued under credentialed test.
Verified without credentials:
cargo build -p protect-fficlean, the crate testsuite green (310 passed) with
cargo fmt --checkclean, and awasm32-unknown-unknownbuild clean — the last of those being the target where across-workspace path dependency would break first, since the EQL workspace never
otherwise builds for wasm32.
Bump
cipherstash-client,cts-common,stack-auth, andstack-profileto 0.42.2, which moves the transitivejsonwebtokendependency from 9.3.1 to 10.4.0, resolving CVE-2026-25537 (a JWT claim-validation type-confusion bug that could allow bypassingnbf/expchecks). No API changes.@cipherstash/stack@1.2.0
Patch Changes
@cipherstash/stack-drizzle@1.2.0
Patch Changes
@cipherstash/stack-supabase@1.2.0
Patch Changes
@cipherstash/protect-ffi-darwin-arm64@0.32.1
@cipherstash/protect-ffi-darwin-x64@0.32.1
@cipherstash/protect-ffi-linux-arm64-gnu@0.32.1
@cipherstash/protect-ffi-linux-x64-gnu@0.32.1
@cipherstash/protect-ffi-linux-x64-musl@0.32.1
@cipherstash/protect-ffi-win32-x64-msvc@0.32.1
@cipherstash/wizard@1.2.0
@cipherstash/e2e@0.0.6
Patch Changes
@cipherstash/basic-example@1.2.17
Patch Changes
@cipherstash/prisma-example@0.1.3
Patch Changes
@cipherstash/bench@0.0.8
Patch Changes
@cipherstash/test-kit@0.0.4
Patch Changes