Skip to content

feat: emit StorageEnvelope compressed_data as msgpack bin (protocol 1.1) (LAB-866) - #59

Merged
27Bslash6 merged 1 commit into
mainfrom
lab-866-writer-flip-bin
Jul 26, 2026
Merged

feat: emit StorageEnvelope compressed_data as msgpack bin (protocol 1.1) (LAB-866)#59
27Bslash6 merged 1 commit into
mainfrom
lab-866-writer-flip-bin

Conversation

@27Bslash6

@27Bslash6 27Bslash6 commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Writer flip — rollout step 3 of the protocol 1.1 readers-first plan (LAB-764, decision record decisions/envelope-bin-encoding.md, spec PR cachekit-io/protocol#44). Resolves LAB-866. References #54 (GitHub close deferred until stage 5 confirms SDK parity).

The diff

  • src/byte_storage.rs: #[serde(with = "serde_bytes")] on StorageEnvelope.compressed_data — the one functional change. checksum: [u8;8], original_size, format untouched (normative scope exclusions). serde_bytes was already a non-optional dependency; zero dep changes.
  • tests/wire_format_vectors.rs: re-encode byte-identity (store-level + codec-level) switched from the legacy set to the *_bin set, exactly at the switch points stage 2 (test: prove dual-decode of legacy + bin envelopes, re-pin protocol 1.1 fixture (LAB-791) #57) marked. Decode-identity keeps running against BOTH sets, forever.
  • tests/dual_decode.rs: reader roles inverted — the crate struct is now the serde_bytes shape, so the local twin became StorageEnvelopeLegacy (plain Vec<u8>), permanently proving legacy readers accept bin and legacy wire still decodes. Width-boundary tests (bin8/bin16/bin32) now exercise the real writer. A re-encode assert that became an exact duplicate of envelope_codec_roundtrip_byte_identical was deleted (panel cut).
  • benches/hot_path.rs: new 64mib_incompressible group (envelope codec + store/retrieve e2e) — the LAB-510-harness proof workload, with a self-enforcing incompressibility assert.
  • README.md: wire-format paragraph now states the writer emits bin.

Benchmark proof (64 MiB incompressible, this machine, criterion --baseline legacy)

Metric Before (array-of-ints) After (msgpack bin) Delta
Envelope overhead vs payload 101,189,485 B (1.508×) 67,372,070 B (1.0039×) −33.4 MB
envelope_encode 410 ms (156 MiB/s) 56 ms (1.11 GiB/s) ~7.3×
envelope_decode 446 ms (143 MiB/s) 40 ms (1.57 GiB/s) ~11.2×
store() e2e 406 ms (158 MiB/s) 113 ms (567 MiB/s) ~3.6×
retrieve() e2e 486 ms (132 MiB/s) 82 ms (778 MiB/s) ~5.9×

Reproduces the LAB-764 decision-memo reference measurement (1.508→1.0039×, encode 6–7×, decode 9–11×, store() off the ~150 MB/s msgpack-encode ceiling).

⚠️ Merge-order constraint (for ray)

The v0.4.0 RELEASE PR (release-please's) must not merge before the LAB-865 release.yml fix is on main. Status: #58 is already merged ✓ — so the remaining order is simply: merge this PR → merge the release PR. This PR does not touch .github/. feat: type minor-bumps 0.3.0 → 0.4.0.

Expert panel (crypto/protocol gate, high stakes) — PASSED

  • CHECKPOINT AAD independence: CONFIRMED — no encryption code in the diff; AAD is caller-supplied, never derived from envelope serialization; envelope bytes remain the AES-GCM plaintext (AAD v0x03 metadata-only).
  • CHECKPOINT scope: CONFIRMED — serde_bytes on compressed_data only; byte-identity against protocol-pinned *_bin vectors proves checksum/original_size/format bytes unchanged.
  • CHECKPOINT format untouched: CONFIRMED.
  • CHECKPOINT bin length-header validation: CONFIRMED — retrieve()/validate() cap input at 512 MiB pre-deserialize; rmp-serde 1.3.1 read_slice bounds-checks declared bin lengths against the buffer before any allocation.
  • Applied findings: README no longer hardcodes an unreleased crate version; duplicate re-encode assert deleted; bench incompressibility now asserted.
  • Rejected findings (with reason): Cargo.toml version bump (release-please owns it; merge-order note covers the gap); bench/test incompressible() dedup via #[path] include (couples bench to test internals to save 12 deterministic lines).
  • Deferred MUST: the fixture-level bin16/bin32 width-boundary vector (protocol-repo change + re-vendor) is filed as LAB-868 — panel verdict: not a blocker since real-writer bin8/16/32 coverage is CI-enforced in-repo; fixture pinning protects the other SDKs and needs a protocol PR this diff cannot atomically carry.

Docs gate

README wire-format section updated (writer emission + scope exclusion). Protocol spec already correct (protocol 1.1). Rust doc-comments in the two proof test files rewritten to post-flip reality. SDK-side docs are stage 5 (per rollout plan). No other doc surface claims the legacy encoding — verified by repo-wide grep for pre-flip tense.

Summary by CodeRabbit

  • Compatibility

    • Updated protocol 1.1+ wire-format guidance to clarify binary encoding for compressed data.
    • Legacy envelopes remain readable indefinitely.
    • Checksum encoding remains unchanged for wire-format compatibility.
  • Documentation

    • Added clearer explanations of serialisation behaviour and legacy encoding support.
  • Testing

    • Expanded coverage for reading legacy and current formats, binary encoding widths, and byte-identical re-encoding.
    • Strengthened validation of storage and retrieval across supported formats.
  • Performance

    • Added coverage for large, 64 MiB envelope encoding and decoding workloads.

….1) (LAB-866)

Writer flip, rollout step 3 of the readers-first plan (LAB-764):
serde_bytes on compressed_data only — checksum stays array-of-ints per
the protocol's normative scope exclusion. Re-encode byte-identity now
asserts against the *_bin vector set; decode-identity keeps running
against BOTH sets forever. dual_decode's local twin struct becomes the
legacy-reader stand-in, keeping the permanent proof that pre-1.1
readers accept bin wire.

64 MiB incompressible (hot_path bench, new 64mib_incompressible group):
envelope overhead 1.508x -> 1.0039x, encode ~7.3x faster, decode
~11.2x faster, store() e2e 158 -> 567 MiB/s.

GH #54 close deferred to stage 5 (SDK parity);
see protocol PR #44 and cachekit-core#57 (stage 2).

Expert panel (high stakes) passed: AAD independence, compressed_data-
only scope, format/checksum untouched, bin length headers bounds-checked
pre-allocation all CONFIRMED. Fixture-level bin16/bin32 width-boundary
vector (deferred MUST) tracked as LAB-868.
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: fd9cbf6d-9378-46ee-a614-6914fdd823f2

📥 Commits

Reviewing files that changed from the base of the PR and between 88c7c7e and 5a1fd65.

📒 Files selected for processing (5)
  • README.md
  • benches/hot_path.rs
  • src/byte_storage.rs
  • tests/dual_decode.rs
  • tests/wire_format_vectors.rs

Walkthrough

The PR documents the msgpack bin writer format, updates compatibility tests to validate legacy and current readers, and adds a deterministic 64 MiB envelope codec benchmark.

Changes

Wire-format compatibility

Layer / File(s) Summary
Wire-format contract and current-writer vectors
README.md, src/byte_storage.rs, tests/wire_format_vectors.rs
Documents serde_bytes bin encoding for compressed_data, preserves the checksum array format, and moves byte-identical assertions to current *_bin vectors.
Dual-reader compatibility validation
tests/dual_decode.rs
Validates decoding through both legacy Vec<u8> and shipped StorageEnvelope readers, including retrieval and bin-width marker coverage.
64 MiB envelope codec benchmark
benches/hot_path.rs
Benchmarks envelope encode/decode and end-to-end store/retrieve operations using a deterministic incompressible 64 MiB payload.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarises the main change: StorageEnvelope compressed_data now emits msgpack bin for protocol 1.1.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch lab-866-writer-flip-bin

Comment @coderabbitai help to get the list of available commands.

@kodus-27b

kodus-27b Bot commented Jul 26, 2026

Copy link
Copy Markdown

Kody Review Complete

Great news! 🎉
No issues were found that match your current review configurations.

Keep up the excellent work! 🚀

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Validate Business Logic: Ask Kody to validate your code against business rules by adding a comment with the @kody -v business-logic command.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Bug
Performance
Security
Business Logic

Access your configuration settings here.

@27Bslash6

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@27Bslash6
27Bslash6 merged commit c691087 into main Jul 26, 2026
33 checks passed
@27Bslash6
27Bslash6 deleted the lab-866-writer-flip-bin branch July 26, 2026 22:55
27Bslash6 added a commit to cachekit-io/cachekit-ts that referenced this pull request Jul 29, 2026
…-901) (#91)

Closes LAB-901. Parent: LAB-764 stage 5 (protocol 1.1 rollout,
TypeScript leg).

## What

Bump `cachekit-core` 0.3.0 → 0.4.0 in both native bindings —
`cachekit-core-ts` (NAPI) and `cachekit-core-wasm` — and prove the
protocol 1.1 wire change through the real TS stack. Core 0.4.0 emits
`StorageEnvelope.compressed_data` as msgpack **bin**
([core#59](cachekit-io/cachekit-core#59), spec
[protocol#44](cachekit-io/protocol#44));
pre-0.4.0 array-of-integers envelopes remain readable forever
(dual-read).

No ts-side serialization code changes — the codec is single-sourced in
cachekit-core. The diff is the two Cargo pins + locks, the re-vendored
spec vectors, and tests.

## Byte-verification (proven, not asserted)

- **Re-vendored** `protocol/test-vectors/wire-format.json` v1.1.0 (6
legacy + 6 `*_bin` vectors) and now drive the **full vector set through
both lanes**: NAPI (Node lane, `test/protocol`) and wasm inside real
workerd (`test/workers`).
- **bin emit**: `pack` output equals every `*_bin` ground-truth envelope
byte-for-byte, in both bindings — which also pins the two bindings
byte-identical to each other and to every other SDK.
- **Legacy read**: all 6 legacy vectors plus the pre-0.4.0 canonical
fixture decode through the real retrieve path (permanent dual-read
proof).
- **Marker assert**: fresh packs of arbitrary payloads (bin8- and
bin16-sized, incompressible included) carry the msgpack bin marker and
round-trip identically.
- Local verification against ground truth before the fixtures were
written: freshly built NAPI and wasm artifacts both reproduce
`simple_string_bin` exactly and decode the legacy `simple_string`
envelope.

## Checks

- Node lane: 659 passed | 1 skipped. Workers lane (workerd): 97 passed.
Lint, prettier, type-check green.
- wasm size budget: 54,992 B gzipped (< 100 KB), API drift check clean.
- `.secrets.baseline` refreshed — hex test vectors are line-pinned there
(pre-existing pattern), and the vector additions moved them.

## Docs gate

No README or docs.cachekit.io statement describes the `compressed_data`
field encoding (checked SDK READMEs + docs repo
`envelope`/`compressed_data` hits); container-level claims ("LZ4 +
xxHash3-64", byte-compatibility across NAPI/wasm) remain true. Test-file
headers updated to protocol v1.1 with the dual-read note. Nothing else
needed changing.
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