Skip to content

fix(prisma-next): reclassify EQL install as additive so fresh-database db init passes - #820

Open
coderdan wants to merge 2 commits into
remove-v2from
fix/eql-bundle-operation-class
Open

fix(prisma-next): reclassify EQL install as additive so fresh-database db init passes#820
coderdan wants to merge 2 commits into
remove-v2from
fix/eql-bundle-operation-class

Conversation

@coderdan

Copy link
Copy Markdown
Contributor

Problem

Prisma Compute's GitHub preview deploy runs prisma-next db init (additive-only policy) against each branch database. The cipherstash space's install-eql-v3-bundle op is classed data, so every preview deploy of an app using @cipherstash/prisma-next fails:

PN-RUN-3020: Operation cipherstash.install-eql-v3-bundle has class "data"
which is not allowed by policy. Policy only allows: additive.

Hit in a live dogfooding run (rc.4 consumer app + Compute push-to-deploy).

Why data was there, and why it's safe to change

The in-file rationale says data satisfies the aggregate integrity checker's no-op self-edge rule (sameSourceAndTarget, PN-MIG-CHECK-007). Verified against migration-tools 0.16.0: that rule only fires when from === to. The genesis edge runs from: null → the empty-storage hash — not a self-edge — so additive passes the checker. Empirically confirmed both ways: flipping the upgrade edge (a true A → A self-edge) to additive trips PN-MIG-CHECK-007; flipping the install edge does not.

additive is also the truthful class on the policy axis: the bundle only CREATEs its own schemas, domains, and functions; it cannot damage user data.

Keeping fresh databases off the upgrade self-edge

The 3.0.2 upgrade edge must keep data (true self-edge). So the re-emitted install edge now also carries the 3.0.2 upgrade invariant via a no-SQL additive carrier op — legitimate because the baked bundle already IS the pinned 3.0.2 release. computeExtensionSpaceApplyPath picks the shortest invariant-covering path, so a fresh database satisfies the head ref from the single all-additive genesis edge and never walks the upgrade edge. Databases installed at 3.0.0 still upgrade through it via migrate (all classes allowed). Head ref unchanged.

Consumer impact (pre-GA, deliberate)

One-time re-emit of a published artefact: the install package's migrationHash changes (baked SQL digest unchanged). RC consumers with a vendored migrations/cipherstash/ refresh the install package's ops.json + migration.json (or delete the space dir and re-run migration plan). Frozen-hash test re-pinned with a comment recording the exception; example app's vendored copy synced.

Verification

  • packages/prisma-next v3 suite: 208/208 (3 pins updated to the new shape)
  • Consumer app end-to-end: migration check passes; db init on a fresh database now succeeds (previously PN-RUN-3020), applying the cipherstash space additively — eql_v3 schema present, both encrypted-column domains created, database signed
  • Existing already-migrated databases: marker hash + invariants unchanged → migrate/db verify no-ops, confirmed on the dogfooding app

Related: #819 (prisma-next backfill support, same dogfooding run).

`prisma-next db init` enforces an additive-only operation policy, but the
cipherstash space's install-eql-v3-bundle op was classed `data`, so every
fresh-database init — including Prisma Compute's GitHub preview deploys —
failed with PN-RUN-3020 (POLICY_VIOLATION).

The `data` class existed to satisfy the aggregate integrity checker's
no-op self-edge rule, but that rule only fires when from === to; the
genesis edge runs from: null → the empty-storage hash and is not a
self-edge, so `additive` — the truthful class for a bundle that only
CREATEs its own schemas/domains/functions — passes the checker.

The 3.0.2 upgrade edge IS a true self-edge and must keep its `data`
class. To stop fresh databases needing that edge at all, the re-emitted
install edge now also carries the 3.0.2 upgrade invariant via a no-SQL
additive carrier op (the baked bundle is already the pinned 3.0.2
release). The shortest-path planner then satisfies the head ref from the
single all-additive genesis edge; databases installed at 3.0.0 still
reach 3.0.2 through the upgrade edge via `migrate`, whose policy allows
all classes.

This is a one-time authorized pre-GA re-emit of the published install
artefact (migrationHash changes). RC consumers with a vendored
migrations/cipherstash/ must refresh the install package's ops.json and
migration.json (or delete the space dir and re-run migration plan). The
baked SQL digest is unchanged. The example app's vendored copy is synced.

Verified end-to-end against a consumer app: `prisma-next migration check`
passes, and `prisma-next db init` on a fresh database applies the
cipherstash space additively (previously PN-RUN-3020), installing eql_v3
with both encrypted-column domains, then signs the database.
@coderdan
coderdan requested a review from a team as a code owner July 28, 2026 10:16
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e42223a9-e374-4aa9-a928-3f777e9ed87b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/eql-bundle-operation-class

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@changeset-bot

changeset-bot Bot commented Jul 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b22cc69

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@cipherstash/prisma-next Patch
@cipherstash/stack Patch
stash Patch
@cipherstash/prisma-next-example Patch
@cipherstash/bench Patch
@cipherstash/stack-drizzle Patch
@cipherstash/stack-supabase Patch
@cipherstash/test-kit Patch
@cipherstash/basic-example Patch
@cipherstash/e2e Patch
@cipherstash/wizard Patch

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

]
},
{
"id": "cipherstash.install-provides-eql-v3-3-0-2",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be 3.0.4.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in b22cc69 — @cipherstash/eql bumped to 3.0.4 across prisma-next/cli/stack, the baseline re-emitted baking the 3.0.4 bundle (label + digest updated), and a new data-classed 3.0.4 upgrade self-edge added for databases on an older bundle. The baseline now carries both upgrade invariants so fresh-database db init still takes the single all-additive edge. Verified on a fresh database: eql_v3.version() reports 3.0.4. Example vendored space synced; changeset added.

Addresses review on #820: the install baseline must target the latest
EQL release, not 3.0.2.

- @cipherstash/eql pinned 3.0.2 -> 3.0.4 in prisma-next, cli, and stack
  (lockfile updated via the one-off cooldown bypass; @cipherstash/eql is
  already in minimumReleaseAgeExclude as a first-party package)
- the re-emitted install baseline now bakes the eql-3.0.4 bundle and
  carries BOTH upgrade invariants (3.0.2 + 3.0.4) via no-SQL additive
  carrier ops, so fresh-database `db init` still satisfies the head ref
  from the single all-additive genesis edge
- new `data`-classed 3.0.4 upgrade self-edge
  (20260728T0000_upgrade_eql_v3_3_0_4) for databases installed at an
  older bundle, walked via `migrate` only
- head ref gains the 3.0.4 invariant; descriptor wires the new edge;
  example vendored space synced; changeset added

Tests: prisma-next 345 passed (frozen-hash pins re-pinned for the
re-emitted baseline, new edge pinned); stack 1107; cli 947.

Verified live against a consumer app: fresh-database `db init` applies
the cipherstash space additively and `eql_v3.version()` reports 3.0.4.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the @cipherstash/prisma-next contract-space migration graph so fresh-database prisma-next db init can succeed under an additive-only policy, while still preserving data-classed self-edge upgrades for already-installed databases. It also bumps the pinned @cipherstash/eql bundle to 3.0.4 across the repo and re-pins the frozen migration artefact assertions accordingly.

Changes:

  • Reclassify the v3 baseline install op as additive and add additive, no-SQL “invariant carrier” ops so a fresh database satisfies head invariants without traversing data self-edges.
  • Add a new data-classed 3.0.4 upgrade self-edge migration and extend head invariants to include the 3.0.4 invariant.
  • Bump pinned @cipherstash/eql to 3.0.4 (cli/stack/prisma-next) and sync the example’s vendored cipherstash migration refs; add a changeset.

Reviewed changes

Copilot reviewed 16 out of 21 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pnpm-lock.yaml Updates lockfile entries for @cipherstash/eql@3.0.4.
packages/stack/package.json Pins devDependency @cipherstash/eql to 3.0.4.
packages/cli/package.json Pins dependency @cipherstash/eql to 3.0.4.
packages/prisma-next/package.json Pins dependency @cipherstash/eql to 3.0.4.
packages/prisma-next/src/extension-metadata/constants-v3.ts Adds 3.0.4 upgrade migration name and invariant constant.
packages/prisma-next/src/exports/control.ts Publishes the new 3.0.4 upgrade migration edge in the descriptor.
packages/prisma-next/migrations/refs/head.json Extends head invariants to include the 3.0.4 upgrade invariant.
packages/prisma-next/migrations/20260601T0100_install_eql_v3_bundle/migration.ts Reclassifies baseline install op to additive and adds invariant-carrier ops.
packages/prisma-next/migrations/20260601T0100_install_eql_v3_bundle/migration.json Updates baseline provided invariants and migrationHash.
packages/prisma-next/migrations/20260728T0000_upgrade_eql_v3_3_0_4/migration.ts Adds a new 3.0.4 upgrade self-edge migration (data-classed).
packages/prisma-next/migrations/20260728T0000_upgrade_eql_v3_3_0_4/migration.json Records the 3.0.4 upgrade edge metadata and migrationHash.
packages/prisma-next/test/v3/migration-v3.test.ts Re-pins frozen migration artefact hashes/digests and adds assertions for the 3.0.4 upgrade edge + carriers.
packages/prisma-next/test/descriptor.test.ts Updates descriptor expectations for three migrations and deduped invariant coverage.
examples/prisma/migrations/cipherstash/refs/head.json Syncs example vendored head ref invariants (adds 3.0.4).
examples/prisma/migrations/cipherstash/20260601T0100_install_eql_v3_bundle/migration.json Syncs example vendored baseline migration metadata to match re-emit.
examples/prisma/migrations/cipherstash/20260728T0000_upgrade_eql_v3_3_0_4/migration.json Adds example vendored 3.0.4 upgrade migration metadata.
.changeset/eql-additive-install-304.md Adds a changeset describing the db init fix and EQL 3.0.4 bump.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file
Comments suppressed due to low confidence (1)

packages/prisma-next/test/v3/migration-v3.test.ts:141

  • The test title/comment says there are "two" additive ops, but the baseline migration now contains three ops (install + two invariant carriers). This mismatch makes the test misleading for future maintainers reading failures or grepping for expected behavior.
  it('installs under the v3 invariants with two additive rawSql ops', () => {
    // Two ops, both `additive`, so fresh-database `db init` (additive-only
    // policy) can walk this genesis edge: the bundle install itself, plus a
    // no-SQL carrier op that declares the 3.0.2 upgrade invariant (the baked
    // bundle IS the pinned release, so a fresh install lands at 3.0.2 and

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +115 to +120
// Invariant carrier: the install op above already ships the pinned
// release's bundle (eql-3.0.2 — `readVerifiedInstallSql()` is digest-
// verified against the installed manifest), so a fresh database that
// walks this genesis edge IS at the pinned release (3.0.4, a
// superset of every earlier v3 surface, so the 3.0.2 invariant is
// honestly satisfied too). Declaring the upgrade invariants here
Comment on lines 104 to +107
migrationHash:
'sha256:2c8739076699b81bcf515f1f8ff23501ff1f2582b933cfd80c5fb5bcc3de9e12',
'sha256:fc495f7f59e6d18ae8e3df594a38898263ca91f8f5fb5f625bff20d04a0d7223',
installSqlSha256:
'05860ae47b3760cbba9842b22ddf89cf3f03aa49c33b6386f736c271784094b1',
'63104a81aac0aebd59fac3765cbe92c3364a7ecbb0bce99e53fbe518d30a0641',
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants