chore(stack): source EQL v3 bundle from @cipherstash/eql#590
Conversation
The v3 install SQL was a 43,339-line bundle hand-vendored into the test tree with no generator script and no recorded provenance. Nothing tied it to a released EQL version, and nothing detected drift from the protect-ffi payload format it has to match. Its eql_v3.version() reports DEV — it was never a release. @cipherstash/eql publishes the SQL bundle and the TypeScript wire types from the same eql-bindings commit, so one pinned version supplies both. Read the bundle from readInstallSql() and delete the fixture. Replace the staleness sentinel with a version check. It previously probed to_regtype('public.timestamp'), a hand-picked type meant to exist only in the newest bundle. That domain exists in the released bundle too, so the check would have reported a stale install as current and left the suite silently exercising the wrong SQL. eql_v3.version() carries the release identity, so the check needs no maintenance when the pin moves; to_regprocedure() yields NULL rather than raising on an empty database. The published bundle renames query-operand domains from public.<type>_query to eql_v3.query_<type>. Nothing here referenced those names: 0 functions accept the old domains, 425 accept the new ones, and protect-ffi 0.28.0 operands round-trip unchanged. @cipherstash/eql is a devDependency — nothing in src/ imports it, and the package's files array already excludes __tests__. It is added to minimumReleaseAgeExclude alongside protect-ffi and auth: it is first-party, released in lockstep, and the 7-day cooldown would otherwise block an alpha. The image pin stays at 17-2.3.1. That image supplies eql_v2; v3 now arrives at runtime from the package. The published v3 images are v3-only and would drop eql_v2 out from under the v2 suites. Verified against a clean postgres-eql:17-2.3.1 container: full packages/stack suite 1,055 passed / 0 failed, including the 57-test ORE matrix; a stale DEV install is detected and reinstalled to 3.0.0-alpha.3; the skip-gate still skips without DATABASE_URL; npm pack ships no tests, no SQL, no new dep.
🦋 Changeset detectedLatest commit: 70e9f19 The changes in this PR will be included in the next version bump. This PR includes changesets to release 6 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
CI failed on a fresh database with
`PostgresError: schema "eql_v3" does not exist` (3F000) from hasCurrentEqlV3.
Postgres resolves function references while parsing a statement, before any
branch of it executes. So in
SELECT CASE
WHEN to_regprocedure('eql_v3.version()') IS NULL THEN NULL
ELSE eql_v3.version()
END
the ELSE branch is resolved even when the guard would have short-circuited:
the statement raises 3F000 when the eql_v3 schema is absent, and 42883 when
the schema exists but the function does not. The guard only ever succeeded
when it was not needed.
to_regprocedure() itself is fine — it takes the name as a string and yields
NULL rather than raising. Split the probe into its own statement and only
then call eql_v3.version(), so the call is parsed after existence is known.
Every local run had already installed EQL v3, so the empty-database path was
never exercised — the case the previous commit message claimed was safe.
Verified against a fresh ghcr.io/cipherstash/postgres-eql:17-2.3.1 (no eql_v3):
v3 suites 237 passed; full packages/stack suite 1,055 passed / 0 failed. Also
covers the schema-present-but-no-version() case: reinstalls rather than raising.
There was a problem hiding this comment.
Pull request overview
This PR updates @cipherstash/stack’s EQL v3 test/install workflow to source the v3 SQL bundle (and its release identity) from the published @cipherstash/eql package instead of a large, hand-vendored SQL fixture, and makes the “is the DB current?” sentinel robust by checking eql_v3.version() against the pinned release manifest.
Changes:
- Add
@cipherstash/eql@3.0.0-alpha.3as an exact-pinneddevDependencyforpackages/stackand wire the v3 installer helper to executereadInstallSql(). - Replace the previous type-based “current bundle” sentinel with a release-identity check using
eql_v3.version()vsreleaseManifest.eqlVersion. - Update docs and add a changeset documenting the switch away from the vendored SQL fixture.
Reviewed changes
Copilot reviewed 6 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-workspace.yaml | Excludes @cipherstash/eql from the minimum release age cooldown to allow installing the newly-pinned first-party package. |
| pnpm-lock.yaml | Records the locked @cipherstash/eql@3.0.0-alpha.3 dependency. |
| packages/stack/scripts/install-eql-v3.ts | Prints the pinned EQL v3 release version after ensuring installation. |
| packages/stack/package.json | Adds @cipherstash/eql as an exact devDependency for packages/stack. |
| packages/stack/tests/helpers/eql-v3.ts | Reads and installs the SQL bundle from @cipherstash/eql and switches staleness detection to eql_v3.version() comparison. |
| docs/eql-v3-ord-term-ordering-defect.md | Updates references from the vendored SQL fixture to the published @cipherstash/eql bundle location/API. |
| .changeset/eql-v3-bundle-from-package.md | Adds a patch changeset describing the bundle source change and the new staleness sentinel. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Replaces the hand-vendored EQL v3 SQL bundle with the published
@cipherstash/eqlpackage.packages/stackinstalled EQL v3 from a 43,339-line SQL bundle committed to the test tree, hand-vendored in 63ca540 with no generator script and no recorded provenance. Nothing tied it to a released EQL version, and nothing detected drift from theprotect-ffipayload format it has to match. Itseql_v3.version()returnsDEV— it was never a release.@cipherstash/eqlpublishes the SQL bundle and the TypeScript wire types from the sameeql-bindingscommit, so one pinned version supplies both. This PR reads the bundle viareadInstallSql()and deletes the fixture.The load-bearing change: the staleness sentinel
hasCurrentEqlV3()gated reinstall onto_regtype('public.timestamp')— a hand-picked type meant to exist only in the newest bundle. That domain exists in the released bundle too. Swapping the source without touching the sentinel would have reported a stale install as current, skipped the install, and left the suite silently exercising the old SQL while appearing green.It now compares
eql_v3.version()againstreleaseManifest.eqlVersion. That carries the release identity, so it needs no maintenance when the pin moves.to_regprocedure()yieldsNULLrather than raising, so an empty database (or one predatingeql_v3.version()) reads as stale and gets installed.Every hand-picked sentinel decays this way — the previous one,
public.text_search, had already been replaced for exactly the same reason.The domain rename is a non-event
The published bundle renames query-operand domains from
public.<type>_querytoeql_v3.query_<type>. Nothing in this repo referenced those names. Verified against a live database after installing alpha.3:public.*_queryeql_v3.query_*protect-ffi@0.28.0operands round-trip unchanged througheq/contains/gte/lte/ OREFunction names are identical across both bundles (1,758 each); only operand signatures moved.
Verification
Run against a pristine
ghcr.io/cipherstash/postgres-eql:17-2.3.1container (fresh volume, soinitdbactually seeds EQL):packages/stacksuite: 1,055 passed, 0 failed across 48 files — includingv3-matrix/matrix-live-pg.test.ts(57 tests, the ORE ordering matrix), which had never been exercised against a released bundle.DEVbundle is detected and reinstalled to3.0.0-alpha.3; a second run is idempotent.env -u DATABASE_URL→ suite SKIPPED, 0 failures.pnpm build,pnpm test:types(60 tests),biome checkclean.npm pack --dry-runships no__tests__, no SQL, and no new runtime dependency.Review notes
Two things deserve a second pair of eyes:
pnpm-workspace.yamlgains aminimumReleaseAgeExcludeentry. alpha.3 is days old and the repo's 7-day supply-chain cooldown blocked the install outright.@cipherstash/eqlis first-party and released in lockstep withprotect-ffi, which is already excluded — so this matches the list's documented intent ("first-party packages we publish or integrate against directly"). It is still a security-relevant setting change.@cipherstash/eqlis adevDependency, exact-pinned to3.0.0-alpha.3. Nothing insrc/imports it, andfilesalready excludes__tests__. No range — an alpha SQL bundle that opens withDROP SCHEMA … CASCADEmust never float.Not in scope
17-2.3.1. That image supplieseql_v2; v3 now arrives at runtime from the package. I checked the published v3 images (17-3.0.0-alpha.2): they are v3-only and dropeql_v2entirely, which would breaksearchable-json-pg,protect,cli,drizzle, andprisma-next. There is also no alpha.3 image, and it wouldn't matter — the version check would reinstall over it.cli/drizzle/prisma-nextremain oneql-2.3.1/ theeql_v2schema.@cipherstash/eqlships v3 only.src/eql/v3/columns.tsdomain constants stay hand-written. TheireqlTypestrings are metadata only —build()emitscast_as+ capability-derivedindexes, never the domain name.Unrelated findings
packages/prisma-next/src/migration/eql-bundle.tscites a regeneration scriptscripts/vendor-eql-install.tsthat does not exist. Its 7,655-line vendored bundle has no reproducible provenance.json-schema-to-typescriptis an unreferenced orphandevDependencyinpackages/stack. Left alone as unrelated.public.*_querydomains. Unreferenced and harmless; CI is unaffected (fresh container per run). Only long-lived local dev databases carry them.