Skip to content

feat: add changesets for releasing#1

Merged
calvinbrewer merged 3 commits into
mainfrom
changesets
Nov 16, 2024
Merged

feat: add changesets for releasing#1
calvinbrewer merged 3 commits into
mainfrom
changesets

Conversation

@calvinbrewer

Copy link
Copy Markdown
Contributor

No description provided.

@calvinbrewer
calvinbrewer merged commit 3400946 into main Nov 16, 2024
@calvinbrewer
calvinbrewer deleted the changesets branch November 16, 2024 20:11
calvinbrewer pushed a commit that referenced this pull request Dec 19, 2024
…ption

Implement encryption and decryption
coderdan added a commit that referenced this pull request Jul 8, 2026
The one-shot rule was keyed on `options.databaseUrl` being set, but that field
is populated by two callers meaning different things: the CLI sets it only when
`--database-url` is passed (a genuine one-shot), while `stash init` always sets
it (a resolved URL, just to avoid re-prompting). So init tripped the one-shot
branch and never scaffolded stash.config.ts — leaving every downstream command
to dead-end on "Could not find stash.config.ts".

Make the scaffold intent explicit and caller-owned instead of inferred:

- InstallOptions gains `scaffoldConfig: 'ensure' | 'offer' | 'skip'`.
- runInstall (CLI) passes 'skip' when --database-url is present, else 'offer'.
- init's install-eql passes 'ensure' (create without a yes/no prompt).
- resolveInstallContext switches on scaffoldConfig, not options.databaseUrl.
- offerStashConfig gains an `ensure` mode; also folds the duplicated
  writeFileSync+log into a `writeStashConfig` helper.

Tests: new install-eql.test.ts asserts init requests scaffoldConfig: 'ensure'
(the exact wiring that regressed), plus an ensure-mode scaffold test. Fixed the
stale install-eql comment (installCommand now scaffolds but no longer loads the
config during init).
coderdan added a commit that referenced this pull request Jul 8, 2026
The one-shot rule was keyed on `options.databaseUrl` being set, but that field
is populated by two callers meaning different things: the CLI sets it only when
`--database-url` is passed (a genuine one-shot), while `stash init` always sets
it (a resolved URL, just to avoid re-prompting). So init tripped the one-shot
branch and never scaffolded stash.config.ts — leaving every downstream command
to dead-end on "Could not find stash.config.ts".

Make the scaffold intent explicit and caller-owned instead of inferred:

- InstallOptions gains `scaffoldConfig: 'ensure' | 'offer' | 'skip'`.
- runInstall (CLI) passes 'skip' when --database-url is present, else 'offer'.
- init's install-eql passes 'ensure' (create without a yes/no prompt).
- resolveInstallContext switches on scaffoldConfig, not options.databaseUrl.
- offerStashConfig gains an `ensure` mode; also folds the duplicated
  writeFileSync+log into a `writeStashConfig` helper.

Tests: new install-eql.test.ts asserts init requests scaffoldConfig: 'ensure'
(the exact wiring that regressed), plus an ensure-mode scaffold test. Fixed the
stale install-eql comment (installCommand now scaffolds but no longer loads the
config during init).
coderdan added a commit that referenced this pull request Jul 17, 2026
Review follow-up on the M2 complete-rollout change (finding #1 + #3; also
Copilot's sole inline comment):

- plan's interactivity gate re-inlined `process.stdin.isTTY && CI !== 'true'`,
  which only matches exact lowercase `true` — it misses `CI=1`/`CI=TRUE` and so
  diverged from the shared `isInteractive()` (config/tty.ts, whose `isCiEnv()`
  matches `/^(1|true)$/i`) and from the case-insensitive contract the stash-cli
  skill documents. Swap the inline for `isInteractiveTty()` (compute-once
  preserved) so a CI=1 runner with a TTY takes the non-interactive path.
- Drop the unused `cli` parameter from `confirmCompleteRollout`'s opts (the
  refusal hardcodes the `--yes` hint; `cli` was threaded but never read).

No behaviour change on the documented CI=true / TTY paths. plan-complete-rollout
e2e 2/2 and plan unit 22/22 green; build + biome clean.

Claude-Session: https://claude.ai/code/session_01MxTTPaPP16m6br7Hoab94w
coderdan added a commit that referenced this pull request Jul 17, 2026
…nest exit (rc.2 M2) (#686)

* feat(cli): make `plan --complete-rollout` automatable with --yes + honest exit (rc.2 M2)

`--complete-rollout` skips the production-deploy gate, so it requires explicit
consent. Previously that was an interactive p.confirm with no bypass: a
non-interactive run auto-cancelled (default-no) and exited 0 via CancelledError
— so CI/agents got exit 0 but no plan was drafted, and would assume one existed.

- New `--yes` flag confirms the gate-skip without a prompt (automation path).
- Non-interactive `--complete-rollout` WITHOUT `--yes` now refuses with a
  non-zero exit (CliExit(1)) and points at --yes, instead of silently
  cancelling with exit 0. An interactive decline stays exit 0 (a deliberate
  'no' is not a failure).
- isInteractive is computed once up front (the confirm needs it too).
- Registry + help + `stash-cli` skill updated; messages.plan.* leaders added
  for e2e stability.

Tests: 2 pty-less e2e (refuses+exit-1 without --yes; --yes confirms + proceeds),
plus manifest resolves the new flag. Suite 540 unit / 64 e2e green, code:check
clean. Changeset: stash minor.

Claude-Session: https://claude.ai/code/session_01MxTTPaPP16m6br7Hoab94w

* refactor(cli): use shared isInteractive() in plan; drop dead cli param

Review follow-up on the M2 complete-rollout change (finding #1 + #3; also
Copilot's sole inline comment):

- plan's interactivity gate re-inlined `process.stdin.isTTY && CI !== 'true'`,
  which only matches exact lowercase `true` — it misses `CI=1`/`CI=TRUE` and so
  diverged from the shared `isInteractive()` (config/tty.ts, whose `isCiEnv()`
  matches `/^(1|true)$/i`) and from the case-insensitive contract the stash-cli
  skill documents. Swap the inline for `isInteractiveTty()` (compute-once
  preserved) so a CI=1 runner with a TTY takes the non-interactive path.
- Drop the unused `cli` parameter from `confirmCompleteRollout`'s opts (the
  refusal hardcodes the `--yes` hint; `cli` was threaded but never read).

No behaviour change on the documented CI=true / TTY paths. plan-complete-rollout
e2e 2/2 and plan unit 22/22 green; build + biome clean.

Claude-Session: https://claude.ai/code/session_01MxTTPaPP16m6br7Hoab94w
coderdan added a commit that referenced this pull request Jul 23, 2026
…dback)

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.
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