fix(changeset): the protect-ffi 0.31.0 adoption is a patch, not a major - #874
Conversation
The 2.0.0 in the release PR came from one changeset marked `major` on the grounds that a base64-encoded `clientKey` stopped working. That framing was wrong. Hex has always been the documented and only supported encoding for `config.clientKey` / `CS_CLIENT_KEY` — it is what `stash env` emits, and nothing in the JavaScript stack ever produced or accepted a base64 key. Base64 is the on-disk encoding the Rust `stash-profile` crate uses for `~/.cipherstash/secretkey.json`, handled entirely outside this SDK. The decoder underneath happened to fall back to it, so a key pasted out of that file worked by accident. Removing an undocumented decoder tolerance is not a breaking change to this package's contract, and it should not take `stash`, `wizard` and the three adapters to 2.0.0 with it. The changeset is now `patch`, and the same "it used to be supported" framing is corrected in the `stash-auth` skill and its changeset. The fixed group releases at 1.1.0, off the existing minors.
|
| Name | Type |
|---|---|
| stash | Patch |
| @cipherstash/stack | Patch |
| @cipherstash/basic-example | Patch |
| @cipherstash/e2e | Patch |
| @cipherstash/bench | Patch |
| @cipherstash/stack-drizzle | Patch |
| @cipherstash/stack-prisma | Patch |
| @cipherstash/stack-supabase | Patch |
| @cipherstash/test-kit | Patch |
| @cipherstash/prisma-example | Patch |
| @cipherstash/wizard | Patch |
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a changeset to this PR
📝 WalkthroughWalkthroughThe PR updates authentication documentation to require hex-encoded explicit client keys, rejects base64 values during client construction, preserves base64 for profile-store keys, and changes the package release level from major to patch. ChangesClient key encoding
Estimated code review effort: 1 (Trivial) | ~5 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.changeset/olive-pugs-invite.md:
- Around line 7-15: Update the changeset text around the clientKey encoding
history to clarify that base64 was never intentionally supported or produced by
the JavaScript stack, but was accepted incidentally through the decoder’s
fallback; preserve the distinction between documented hex support and accidental
compatibility with copied profile keys.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: fcfc912a-a36f-48f5-9bf0-ffeb6b25dc39
📒 Files selected for processing (3)
.changeset/lucky-cows-repeat.md.changeset/olive-pugs-invite.mdskills/stash-auth/SKILL.md
| **`clientKey` is hex, and a decoder tolerance that accepted other spellings is | ||
| gone.** Hex has always been the documented and only supported encoding for | ||
| `config.clientKey` / `CS_CLIENT_KEY` — it is what `stash env` emits and what | ||
| the docs and skills have always shown. The decoder underneath happened to fall | ||
| back to standard padded base64, which is the encoding the Rust | ||
| `stash-profile` crate uses for `~/.cipherstash/secretkey.json` on disk; that | ||
| fallback was never part of this package's contract, and nothing in the | ||
| JavaScript stack ever produced or accepted a base64 key. It is now rejected at | ||
| client construction with `invalid clientKey: expected a hex-encoded key`. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Correct the historical acceptance claim.
Line 14 says that the JavaScript stack never accepted a base64 key. The preceding text says that the decoder fallback accepted standard padded base64, and .changeset/lucky-cows-repeat.md says that copied profile keys happened to work. State that base64 was never intentionally supported or produced, but was accepted incidentally.
Proposed wording
-and nothing in the JavaScript stack ever produced or accepted a base64 key.
+and the JavaScript stack never intentionally produced or documented base64; the decoder nevertheless accepted it incidentally.The PR objective states that base64 worked incidentally through decoder fallback.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| **`clientKey` is hex, and a decoder tolerance that accepted other spellings is | |
| gone.** Hex has always been the documented and only supported encoding for | |
| `config.clientKey` / `CS_CLIENT_KEY` — it is what `stash env` emits and what | |
| the docs and skills have always shown. The decoder underneath happened to fall | |
| back to standard padded base64, which is the encoding the Rust | |
| `stash-profile` crate uses for `~/.cipherstash/secretkey.json` on disk; that | |
| fallback was never part of this package's contract, and nothing in the | |
| JavaScript stack ever produced or accepted a base64 key. It is now rejected at | |
| client construction with `invalid clientKey: expected a hex-encoded key`. | |
| **`clientKey` is hex, and a decoder tolerance that accepted other spellings is | |
| gone.** Hex has always been the documented and only supported encoding for | |
| `config.clientKey` / `CS_CLIENT_KEY` — it is what `stash env` emits and what | |
| the docs and skills have always shown. The decoder underneath happened to fall | |
| back to standard padded base64, which is the encoding the Rust | |
| `stash-profile` crate uses for `~/.cipherstash/secretkey.json` on disk; that | |
| fallback was never part of this package's contract, and the JavaScript stack | |
| never intentionally produced or documented base64; the decoder nevertheless | |
| accepted it incidentally. It is now rejected at client construction with | |
| `invalid clientKey: expected a hex-encoded key`. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.changeset/olive-pugs-invite.md around lines 7 - 15, Update the changeset
text around the clientKey encoding history to clarify that base64 was never
intentionally supported or produced by the JavaScript stack, but was accepted
incidentally through the decoder’s fallback; preserve the distinction between
documented hex support and accidental compatibility with copied profile keys.
…se notes reach npm Review findings on the previous commit, all in text it would have published. **"No breaking changes in this package" was false for two of the five.** The same 2.0.0 ships `@cipherstash/stack`'s hex-only `clientKey` — a base64 value is now rejected at client construction — and `stash`'s removal of `stash eql validate --exclude-operator-family`, plus two checks that no longer exit 1. Both are recorded at patch and minor respectively, which is a deliberate maintainer call (#874: an undocumented decoder tolerance is not a contract break, and should not by itself take five packages to 2.0.0). That call is not reversed here — but a reader following "needs no code changes" into a failed client construction is not served by it either, so the note now names both, says where they are, and confines the drop-in claim to users of neither. **"cipherstash/protectjs-ffi, which is now archived" was false.** The repository is live; archiving is the last step of the cutover, after this release. Stated as future, matching the sibling changeset that already had it right. **The notes did not reach the packages they were written for.** `CHANGELOG.md` was absent from `files` in `stack-drizzle`, `stack-supabase`, `stack-prisma`, the protect-ffi wrapper and all six platform packages — so the provenance note aimed at "the package a checker actually installs" shipped nowhere near it, and "its own changelog carries the upgrade steps" pointed a Prisma user at a file absent from their install. Added to all ten. Verified by `npm pack --dry-run`: `stack-drizzle` now carries its 34.3kB CHANGELOG. The platform packages' copies are generated by `changeset version`, and `_build-ffi-artifacts.yml` packs from `changeset-release/main` after that runs, so the file exists at pack time. **`repository.directory` does not point at the crate.** It points at each platform's own stub under `packages/protect-ffi/platforms/`; only `repository.url` moved to `cipherstash/stack`. **The moved CHANGELOG section contradicted itself.** The heading excluded 0.31.0 while its first line included it, and its comment stated a rule stricter than the real invariant — the constraint is headingless prose, since a heading terminates the preceding section. Both corrected, and the comment's claim about npm, false when written, is true now that the file is in `files`. Versions are unchanged: seven FFI packages at minor, six Stack packages at major. `test:scripts` 416 passing; all ten manifests parse.
The release PR (#859) currently proposes 2.0.0 for
stash,@cipherstash/stack,@cipherstash/wizardand the three adapters. That comes from a single changeset (olive-pugs-invite.md) markedmajor, and the reasoning behind that mark is wrong.What the changeset claimed
That a base64-encoded
clientKey"worked on 1.x" and stops working after adopting protect-ffi 0.31.0, so upgrading breaks callers.What is actually true
Hex has always been the documented and only supported encoding for
config.clientKey/CS_CLIENT_KEY. It is whatstash envemits, what the variable table inskills/stash-authhas always shown, and what every example uses. Nothing in the JavaScript stack has ever produced or accepted a base64 key.Base64 is the on-disk encoding the Rust
stash-profilecrate uses for~/.cipherstash/secretkey.json— handled entirely outside this SDK. The decoder underneath (SecretKey::from_hex) happened to fall back to standard padded base64, so a key pasted out of that file worked by accident.Removing an undocumented decoder tolerance is not a breaking change to this package's contract, and it should not drag five other packages in the fixed group to 2.0.0.
Changes
.changeset/olive-pugs-invite.md:major→patch, and the prose reframed — the narrowing is described as the removal of an unsupported spelling, with the troubleshooting hint kept (if construction starts failing, the key is not hex)..changeset/lucky-cows-repeat.mdandskills/stash-auth/SKILL.md: the same "older versions also accepted base64, so a key copied out of that file worked" framing corrected. The skill still tells you the symptom and the fix — it just no longer implies a supported input was withdrawn.The DynamoDB error-code narrowing in that changeset is unchanged and still described; it is a fix, not a breaking change.
Result
The 1.1.0 comes from the pre-existing minors (
getSchemas(), the Lovable handoff target,eql migration --supabase), which are unaffected.Merging this updates #859 in place.
Summary by CodeRabbit
Documentation
Release
@cipherstash/stackrelease classification to a patch release.