Commit b7fa61f
authored
Prisma Next 0.16, payload-identifier routing, and digest-verified baked EQL migration artefacts (#763)
* feat(prisma-next): upgrade to Prisma Next 0.16
All @prisma-next/* deps move 0.14.0 -> 0.16.0 in lockstep. prismaContract
now requires the target's createNamespace factory (0.15 stopped
materialising a placeholder namespace) — added to both configs and the
bundled skill. The PSL interpreter test moves to the CST symbol-table
input. Contracts re-emitted: postgres-schema namespace kind,
StorageColumnTypes maps, scalarList capability; storage hashes unchanged.
* feat(prisma-next): route v3 decoding from the EQL payload's own identifier
Every EQL v3 payload carries its required i: {t, c} identifier, and
ZeroKMS commits the cell key to it — the authoritative routing source.
decode now reads it first (ctx.column kept as fallback for non-v3
documents), and decodeJson builds fully-routed envelopes from it instead
of throwing, unblocking relation include() and aggregate projections.
* feat(prisma-next): bake EQL install SQL into migration artefacts, digest-verified
Replaces runtime injection: the framework applies extension migrations
from on-disk vendored copies without the descriptor, and the seed phase
never refreshes an existing package dir, so injection's environment-
dependent hashes orphaned every consumer copy on each EQL bump
(PN-MIG-5002) and the recomputed hash laundered tampering.
Each migration self-emit now embeds readVerifiedInstallSql() — refused
unless sha256 matches @cipherstash/eql's releaseManifest.installSqlSha256.
One content-addressed identity flows from git through npm to vendored
copies and the DB ledger. CI guards: provenance pin (committed SQL digest
== installed manifest), frozen published-migration hashes, and byte-parity
between the example's vendored space and the shipped artefacts. The
example's stale vendored space is regenerated (stale v2 dir removed).
Also fixes the upgrade migration's stale describe() space hashes.
Follow-ups tracked in #762.
* test(prisma-next): make EQL provenance guard bump-safe; fix stale docs
Addresses code-review findings on the baked-EQL work:
- migration-v3.test.ts: the provenance pin compared each migration's baked
SQL digest against the LIVE @cipherstash/eql manifest, so it self-
destructed on the next EQL bump (frozen 3.0.2 bytes can't match a 3.0.3
manifest) — pushing a maintainer toward re-emitting the published
baseline. Reworked to a PUBLISHED_MIGRATIONS table with per-migration
FROZEN digests (identity + baked-SQL, tied to each migration's own
release) plus one bump-safe lockstep check (the installed release must be
baked by SOME published migration) and an on-disk completeness check (no
unpinned or stale migration dirs).
- descriptor.test.ts: the 'injects the runtime EQL install SQL' test still
named and described the deleted sentinel-injection design and compared
against a live readInstallSql() (also bump-unsafe). Rewritten to assert
the op carries the baked bundle verbatim, without the live comparison;
dropped the now-unused import.
- DEVELOPING.md: refreshed the sections that still documented the sentinel/
runtime-injection design and instructed re-emitting published migrations
(the exact action the new doctrine and frozen-hash guard forbid); added
the second (upgrade) migration to the layout and invariants.
Reviewed in this branch; follow-ups (#4/#6/#8 payload-routing edges,
efficiency items) tracked separately.
* docs(prisma-next): document why v3 decodeJson needs no NULL handling
CodeRabbit flagged decodeJson(null) as throwing. It is unreachable: the
SQL runtime null-guards before both codec methods — decodeField before
decode, and sql-orm-client's include-decode loop (plus its many-typed
element path) before decodeJson — so a NULL cell never reaches the codec.
Null-handling is the runtime's contract; returning null here would also
break the framework's decodeJson(json): TInput envelope signature.
Comment only, no behavior change.
* fix(cli,skills): correct 'prisma-next migration apply' -> 'prisma-next migrate'
Prisma Next has no 'migration apply' subcommand — the apply verb is the
top-level 'prisma-next migrate' ('migration' only groups plan/new/show/
status/log/list/graph/check). Running the prescribed 'migration apply'
errors: 'Unknown command: apply. Use prisma-next migrate --to <contract>'.
Fixes the stale name in the stash-prisma-next and stash-cli skills, the
@cipherstash/prisma-next README, and — user-visibly — stash init
--prisma-next's printed next-steps, the init flag help, and the stash eql
install Prisma-Next refusal message. Updated the CLI unit + e2e assertions
that pinned the old string. Historical CHANGELOG entries left as-is.
Surfaced by the rc.4 skilltester run (found at PN 0.14.0, confirmed 0.16.0);
tracked with the other skilltester findings in a follow-up issue.
* feat(prisma-next): warn on v3 decode routing disagreement (review feedback)
Addresses the reviewer's non-blocking note on #763: identifier-first v3
routing decrypts a value by its own `i:{t,c}` identity even when the projected
column disagrees, which removes the implicit cross-check that column-first
routing gave for free (a misplaced value used to fail to decrypt). This
re-surfaces that signal.
`decode` now compares the payload identifier against the projected column and,
on disagreement, emits a `console.warn` naming both — schema identifiers only,
never plaintext/ciphertext. Routing is UNCHANGED: the payload identifier stays
authoritative (ZeroKMS commits the cell key to it). It warns rather than throws,
and dedupes once per distinct mismatch (a per-instance Set), because the same
disagreement is the expected benign shape of an un-re-encrypted column rename —
so it can't spam the hot path or cry wolf on a supported workflow. Mirrors the
once-per-process console.warn pattern already used in @cipherstash/stack.
3 new unit tests: warn-once-per-distinct-mismatch, a fresh warn for a different
mismatch, and no-warn on agreement / no-context (aggregates).
Also documents, in the baked-EQL changeset, that this PR's one-time baseline
re-emit is a deliberate exception to the append-only invariant it introduces
(reviewer note #1).
prisma-next unit suite: 344 pass; build/dts clean; code:check clean.1 parent d25d100 commit b7fa61f
49 files changed
Lines changed: 1529 additions & 1284 deletions
File tree
- .changeset
- examples/prisma
- migrations/cipherstash
- 20260601T0000_install_eql_bundle
- 20260601T0100_install_eql_v3_bundle
- 20260720T0000_upgrade_eql_v3_3_0_2
- refs
- src/prisma
- test/e2e
- packages
- cli
- src
- cli
- commands
- db
- __tests__
- init
- __tests__
- providers
- __tests__
- steps
- tests/e2e
- prisma-next
- migrations
- 20260601T0100_install_eql_v3_bundle
- 20260720T0000_upgrade_eql_v3_3_0_2
- src
- exports
- migration
- v3
- test
- v3
- skills
- stash-cli
- stash-prisma-next
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 0 additions & 28 deletions
This file was deleted.
Lines changed: 3 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
3 | | - | |
| 2 | + | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
Lines changed: 3 additions & 3 deletions
Large diffs are not rendered by default.
Lines changed: 3 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
3 | | - | |
| 2 | + | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
0 commit comments