meta-issue-creation
How an agent files a GitHub issue on cipherstash repos — required structure (Background / Problem / Proposal), dumbed-down…
Deploy a CipherStash encryption rollout to a live environment without losing data — the multi-deploy ladder (schema-add + dual-write → backfill → read cutover → stop dual-writes → drop plaintext), why each deploy boundary exists, what breaks if stages are merged, rollback per
$ npx -y skills add cipherstash/stack --skill stash-deployment --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/stash-deploymentContext preview
The summary Claude sees to decide when to auto-load this skill.
Deploy a CipherStash encryption rollout to a live environment without losing data — the multi-deploy ladder (schema-add + dual-write → backfill → read cutover → stop dual-writes → drop plaintext), why each deploy boundary exists, what breaks if stages are merged, rollback per
name: stash-deployment description: Deploy a CipherStash encryption rollout to a live environment without losing data — the multi-deploy ladder (schema-add + dual-write → backfill → read cutover → stop dual-writes → drop plaintext), why each deploy boundary exists, what breaks if stages are merged, rollback per stage, and how to get CS_* credentials into a build and a runtime. Includes a Prisma Postgres / Prisma Compute section covering push-to-deploy, build-time credential requirements, destructive-migration policy, preview-branch databases, and running backfills against a hosted database. Use when shipping encryption to staging or production, planning the PR sequence for an encryption rollout, wiring deploy credentials, or deploying a CipherStash app to Prisma Compute.
Encrypting a column that already holds live data is a **deployment problem**, not a schema problem. The schema change is trivial; the danger is the window between "the database can hold ciphertext" and "the application reads ciphertext". Getting that window wrong loses data silently — rows written during the gap keep only plaintext, or keep only ciphertext nobody can decrypt, and nothing errors until a user reads the row.
This skill covers how to sequence that across deploys. For the API and the lifecycle model see `stash-encryption`; for the commands see `stash-cli`; for framework specifics see `stash-drizzle` / `stash-supabase` / `stash-prisma`.
Everything here describes **EQL v3**, the only authoring generation. The EQL v2 rollout commands were removed — `stash encrypt cutover` (the old v2 rename swap) now exits with an error on every project. A column that started under v2 finishes the same way as v3: complete the backfill, switch reads to the encrypted column by name, then `stash encrypt drop`. Legacy v2 payloads remain readable; `stash-encryption` covers that.
> **Runner note.** `stash init` adds `stash` to the project as a dev dependency, > so the bare `stash <command>` form used below runs through whichever package > manager the project uses. Before init has run, prefix with your package > manager's one-shot runner (`bunx`, `pnpm dlx`, `yarn dlx`, `npx`). The same > substitution applies to the `prisma-next` and `@prisma/cli` invocations in the > Prisma section.
> **A column goes from plaintext to encrypted across at least four deploys, never one.**
Not a style preference. There is no atomic operation that replaces a populated plaintext column with an encrypted one, because **ciphertext can only be produced by the application**, client-side, holding your keys. No `UPDATE`, no migration, no database-side function can encrypt an existing row. So the plaintext column must stay authoritative — and stay populated — until every row has a ciphertext twin and the deployed code is reading it.
Any plan that adds an encrypted column and drops the plaintext one in the same deploy loses data. Any plan that backfills before dual-writes are live in production loses the rows written during the backfill. The ladder below is the minimum safe shape.
DEPLOY 1 rollout + encrypted twin (nullable) + dual-write
everywhere; reads unchanged
⛔ GATE 1 dual-writes live in the environment that owns the database
out-of-band BACKFILL encrypt historical rows, against the prod DB
migration indexes eql_v3.* extractor indexes + ANALYZE, shipped
through the integration's migration flow
DEPLOY 2 read cutover reads → encrypted column, decrypt at the
boundary; dual-writes stay
⛔ GATE 2 soak — real traffic reads decrypt correctly
DEPLOY 3 stop dual-write writes → encrypted column only; plaintext
column stays, now unwritten
⛔ GATE 3 Deploy 3 live everywhere; coverage re-checked
DEPLOY 4 drop plaintext drop the plaintext column (+ NOT NULL on
encrypted), guarded by an apply-time
coverage re-checkFour deploys, with the backfill and index build between the first two. Each gate is a human decision, not a pipeline step.
Before any application change, make sure the target environment can encrypt at all:
**Drizzle** generates an install migration instead (apply it with `drizzle-kit migrate`), and **Prisma Next** installs it through the migration graph (`prisma-next migrate`).
`stash env --name <app>-<env>`. On most platforms these are needed at **build** time as well as run time (see [Credentials](#credentials-in-a-deployed-environment)).
FFI module — exclude it from bundling (`serverExternalPackages`, esbuild `external`, …). On runtimes that cannot load native modules at all (Cloudflare Workers, Deno, Supabase Edge Functions), bundle `@cipherstash/stack/wasm-inline` instead — it inlines the WASM build, no externalization needed. See `stash-edge`.
Shipping this as its own deploy is cheap and de-risks Deploy 1: a credential or bundling problem surfaces while nothing depends on encryption yet.
One PR, one deploy. It ch
Searchable, application-level encryption for building privacy-first apps
How an agent files a GitHub issue on cipherstash repos — required structure (Background / Problem / Proposal), dumbed-down…
How an agent authors branches, commits, and pull requests on cipherstash/stack — naming, signed commits, the…
How a CipherStash client authenticates — the canonical skill for credentials, auth strategies, and lock context. Covers the…
Drive CipherStash setup and encryption migrations through the `stash` CLI — `init`, `plan`, `impl`, `status`, `auth login`, `eql…
Integrate CipherStash encryption with Drizzle ORM using @cipherstash/stack-drizzle (EQL v3). Covers the types.* encrypted column…
Integrate CipherStash encryption with Amazon DynamoDB using @cipherstash/stack/dynamodb and EQL v3 schemas. Covers item and bulk…