Skip to content

EQL migration artefact redesign: GA follow-ups (installer digest pins, upgrade-window docs, re-baseline cadence) #762

Description

@coderdan

Context

The EQL v3 install migrations in @cipherstash/prisma-next now bake the install SQL into their ops.json at emit time, digest-verified against the @cipherstash/eql release manifest (installSqlSha256) — replacing the runtime-injection design whose environment-dependent migration hashes wedged consumer repos (PN-MIG-5002) on every EQL bump, and whose recomputed hash could never detect a tampered EQL package.

Already enforced in CI (no action needed):

  • Provenance pin — the committed SQL's sha256 must equal the installed @cipherstash/eql manifest's digest; an EQL bump without the matching new migration fails.
  • Frozen-hash pins — published migration hashes are hard-coded in tests; any byte change to published history fails.
  • Vendored-space parity — the example's migrations/cipherstash/ must be byte-identical to the shipped artefacts.

This issue tracks the follow-ups that came out of that work.

Tasks

1. Digest-pin the CLI and stack EQL installers (pre-GA, security)

stash eql install (packages/cli, readV3InstallSql) and the stack install helper (installEqlV3IfNeeded) still execute readInstallSql() from node_modules unverified — the same laundering class the migration path had. The strong fix pins an expected digest in our shipped code (as prisma-next now does), not merely checking the EQL package against its own manifest, which a tampered package would rewrite too. Touches packages/cli + packages/stack; needs the stash-cli skill check per AGENTS.md.

2. Document the EQL upgrade window (GA docs)

Upgrade migrations run DROP SCHEMA eql_v3 CASCADE + recreate. In-flight queries against eql_v3.* fail during that transaction, and any customer-created object depending on those functions (e.g. a functional index over an eql_v3 expression) would cascade-drop. This is an EQL property, not packaging — needs a sentence in the upgrade guide on cipherstash.com/docs.

3. Decide the re-baseline cadence

Each EQL release adds ~2.7 MB (one baked migration) to the tarball and one more replayed install on fresh databases (baseline + every upgrade edge). Correct and idempotent, but linearly wasteful. Decide now that roughly every N releases we cut a fresh genesis migration (new baseline baking current SQL, old chain retained for existing markers) — scheduled maintenance, not a reaction.

4. Dependabot policy for @cipherstash/eql

An automated bump PR will be red by design — the provenance pin demands the new upgrade migration, which a bot can't author. Either add @cipherstash/eql to the Dependabot ignores alongside the auth lockstep set (documenting the manual bump procedure), or accept the red PR as the reminder.

5. Investigate the db-ref planning workflow in the example

A second prisma-next migration plan in examples/prisma replans the whole schema from scratch (from: null) because no db ref (migrations/app/refs/db.json) was ever recorded — resolveFromForPlan treats a missing db ref as greenfield. Affects anyone using the example as a template, and is a prerequisite for the pending two-model include() e2e test. Needs a short look at the intended upstream ref workflow (prisma-next ref set).

Out of scope

More machinery around the seed phase or hash scheme — each failure mode found is covered by a specific tripwire above; the content-addressing makes the rest structurally impossible.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions