Skip to content

feat(ci): release jseql v2#4

Merged
calvinbrewer merged 1 commit into
mainfrom
changesets
Nov 16, 2024
Merged

feat(ci): release jseql v2#4
calvinbrewer merged 1 commit into
mainfrom
changesets

Conversation

@calvinbrewer

Copy link
Copy Markdown
Contributor

No description provided.

@calvinbrewer
calvinbrewer merged commit 2114a45 into main Nov 16, 2024
@calvinbrewer
calvinbrewer deleted the changesets branch November 16, 2024 20:19
calvinbrewer pushed a commit that referenced this pull request Feb 10, 2025
Allow for providing lock context with identity claims
coderdan added a commit that referenced this pull request Jul 8, 2026
…#5)

offerStashConfig returned a truthy DEFAULT_CLIENT_PATH even when it created
nothing, so installCommand's `if (clientPath)` guard scaffolded the encryption
client anyway. Three related fixes, all on this one surface:

- #2: return null when no config is created (declined / cancelled / existing),
  so the caller skips the client scaffold too. Declining now touches nothing.
- #4: in 'offer' mode a non-interactive run no longer silently writes a config
  (+ client) into a bare project — those files import stash / @cipherstash/stack
  and would just re-defer the MODULE_NOT_FOUND crash to the next command. It
  returns null; the missing-config guidance points the user at `stash init`.
  ('ensure'/init still creates unconditionally; init installs the deps.)
- #5: use the shared isCiEnv() (handles CI=1 / CI=TRUE) instead of the raw
  `process.env.CI !== 'true'`, matching the sibling resolveDatabaseUrl so the
  two steps classify the same environment consistently.

Tests: offerStashConfig now asserts null + no write for the non-interactive
offer and existing-config cases; a new e2e drives `eql install` with the URL
from env (non-TTY) and asserts neither a config nor a client is written.
coderdan added a commit that referenced this pull request Jul 8, 2026
…#5)

offerStashConfig returned a truthy DEFAULT_CLIENT_PATH even when it created
nothing, so installCommand's `if (clientPath)` guard scaffolded the encryption
client anyway. Three related fixes, all on this one surface:

- #2: return null when no config is created (declined / cancelled / existing),
  so the caller skips the client scaffold too. Declining now touches nothing.
- #4: in 'offer' mode a non-interactive run no longer silently writes a config
  (+ client) into a bare project — those files import stash / @cipherstash/stack
  and would just re-defer the MODULE_NOT_FOUND crash to the next command. It
  returns null; the missing-config guidance points the user at `stash init`.
  ('ensure'/init still creates unconditionally; init installs the deps.)
- #5: use the shared isCiEnv() (handles CI=1 / CI=TRUE) instead of the raw
  `process.env.CI !== 'true'`, matching the sibling resolveDatabaseUrl so the
  two steps classify the same environment consistently.

Tests: offerStashConfig now asserts null + no write for the non-interactive
offer and existing-config cases; a new e2e drives `eql install` with the URL
from env (non-TTY) and asserts neither a config nor a client is written.
coderdan added a commit that referenced this pull request Jul 22, 2026
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.
coderdan added a commit that referenced this pull request Jul 23, 2026
…ed 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.
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.

1 participant