Skip to content

fix: cross-language IPNS and node-codec verification parity#608

Merged
FSM1 merged 35 commits into
mainfrom
feat/cross-language-ipns-and-node-codec-verification-parity
Jul 11, 2026
Merged

fix: cross-language IPNS and node-codec verification parity#608
FSM1 merged 35 commits into
mainfrom
feat/cross-language-ipns-and-node-codec-verification-parity

Conversation

@FSM1

@FSM1 FSM1 commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Phase 75 — Cross-Language IPNS and Node-Codec Verification Parity

Makes the Rust and TypeScript verification paths reach identical fail-closed
verdicts
for every IPNS record and node-codec body they inspect. All
divergences here are Ed25519-signature-gated, so these are soundness/parity
concerns (a split-brain where one language accepts what the other rejects), not
key or plaintext exposure.

What shipped (SC1–SC3)

  • SC1 — IPNS Validity parity. Shared verify-vector oracle extended with 4
    real-signed invalid cases (expired, wrong ValidityType, two malformed
    RFC3339). TS resolveIpnsRecord now parses RFC3339 with a strict
    branch-for-branch mirror of the Rust parse_rfc3339_to_unix_secs and gates on
    ValidityType === 0; Rust bind_verified gates on ValidityType == 0.
  • SC2 — node-codec fileIv encoding lock. KAT samples switched to
    encoding-unambiguous base64 with a decode-and-assert-length check on both
    languages, so a hex decoder substituted for base64 fails the KAT.
  • SC3 — UUID acceptance-domain parity. Rust build_node_aad and TS
    uuidToBytes tightened to canonical-only, locked by a cross-language oracle.

Parity hardening from the ship-time crypto/privacy review

The review (.planning/security/REVIEW-2026-07-11-phase75-parity.md) surfaced
verdict divergences beyond the original scope; the two material ones are fixed
here on both sides:

  • Duplicate CBOR map keys. TS cborDecode defaulted to last-wins, so a
    signed record with e.g. ValidityType:[1,0] decoded to 0 and was accepted
    while the Rust decoder rejects duplicate keys. TS now decodes with
    rejectDuplicateMapKeys: true; locked by an integration test.
  • RFC3339 fixed-width fields. Rust parse::<T>() accepted a leading +/-
    and overflowing years; TS did not enforce the 4-digit year. Both now use a
    fixed-width digit check (year 4, others 2), rejecting leading signs and
    non-canonical widths identically. Locked by parser tests on both languages.

One LOW benign-direction divergence (a CBOR float 0.0 ValidityType — still
means EOL — passes the TS gate but the Rust integer-major-type check rejects it)
is deferred: .planning/todos/pending/2026-07-11-ts-validitytype-float-vs-integer-cbor-parity.md.

CodeRabbit CLI review

5 findings, all fixed. The material one was another SC3 parity gap: uuidToBytes
accepted a trailing-newline UUID because JS $ (no m flag) also matches
before a final \n, while Rust's is_canonical_uuid_form rejects it on
bytes.len() != 36. Fixed with a length === 36 guard and a \n regression case
added to the shared UUID oracle (run by both languages). The rest were test-rigor
(specific reject-verdict assertions on both sides) and STATE.md/review-doc
bookkeeping. Triage tally: 8 fixed, 1 todo, 1 discarded (fileIv base64
confirm — already locked by the SC2 KAT).

Verification

  • Rust: cipherbox-fuse ipns_verify_vectors, cipherbox-core node_codec_vectors,
    cipherbox-crypto cross_language, cipherbox-api-client --lib ipns — all green.
  • TS: @cipherbox/sdk-core 389 passed, @cipherbox/core 203, @cipherbox/crypto 200.
  • SDK E2E gate: 104/104 IPNS publish/resolve round-trip tests pass, identical
    before and after the resolve-path change (no false-reject of real records). The
    2 tee-republish failures are a pre-existing TEE-worker precondition
    (tee_key_state is empty) unrelated to this phase — no TEE code is touched.
  • 75-SECURITY.md: SECURED. 75-VALIDATION.md: nyquist-compliant.

Also in this branch (bookkeeping)

Closed 3 stranded resolves_phase: 74 todos that phase 74 (merged) actually
resolved but the GSD auto-close left in pending — verified each against the
merged code before moving. See docs(74) commit.

🤖 Generated with Claude Code

FSM1 added 30 commits July 11, 2026 19:48
Entire-Checkpoint: 28cad9348085
…ases

- Parameterize buildCborData to accept Validity string and ValidityType
- Add expired-valid-sig, wrong-validity-type, malformed-rfc3339-trailing-component,
  and malformed-rfc3339-impossible-date cases, each real Ed25519-signed and
  expected_result invalid
- Regenerate tests/vectors/ipns/verify.json to 12 cases; original 8 unchanged

Entire-Checkpoint: e4bebeade437
- GCM body vectors (12-byte fileIv) use base64 samples containing a
  non-hex character; CTR body vectors (16-byte fileIv) use base64
  samples with natural == padding — both are invalid as hex
- add expected_file_iv_len_bytes (12 GCM / 16 CTR) per file body vector
- expected_read_body_hex regenerated via the canonical TS codec
  (encodeReadBody), not hand-edited
- seal_vectors[0].fixed_iv and tests/vectors/crypto/node-aad.json left
  untouched (hex-only harness IVs, no base64 code path)

Entire-Checkpoint: 665933e8071a
…odec KAT

- BodyVector gains expected_file_iv_len_bytes: Option<usize> (present only
  on file-kind vectors; folder/root carry no content.fileIv)
- new node_codec_kat_file_iv_is_base64_not_hex test base64-decodes
  content.fileIv and every versions[].fileIv, asserting decoded length
  equals expected_file_iv_len_bytes — a hex decode would fail on the
  non-hex/padded samples from 75-04 Task 1
- existing round-trip / expected_read_body_hex assertions unchanged

Entire-Checkpoint: 02524fcaefa2
…c KAT

- local base64ToUint8Array mirrors decode.ts's private helper (the
  production decode path), deliberately not the fromHex() helper
- new describe block base64-decodes content.fileIv and every
  versions[].fileIv for every file-kind body vector carrying
  expected_file_iv_len_bytes, asserting decoded length matches — byte-
  identical assertion to the Rust twin (Task 2), driven off the same
  shared VECTORS import
- non-vacuous guard requires at least 2 file body vectors exercised
- existing PRIMARY LOCK assertions unchanged

Entire-Checkpoint: c0a4c666e3cb
- tests/vectors/crypto/uuid-acceptance.json: shared accept/reject cases
  for canonical-only (Option A) UUID acceptance domain
- covers canonical lower/upper, simple-32-hex, loose-hyphen, braced,
  urn:uuid, non-hex, wrong-length, empty forms

Entire-Checkpoint: 521b2bd35fb0
- rejects simple-32-hex and loose-hyphen forms (currently accepted by
  the loose strip-then-check uuidToBytes)
- oracle-driven block over tests/vectors/crypto/uuid-acceptance.json
- RED: 3 tests fail against the current implementation

Entire-Checkpoint: ce39c54d2f7b
- validate the canonical 8-4-4-4-12 hyphenated shape against the raw
  input before hyphen-stripping, rejecting simple-32-hex and
  loose-hyphen forms that were previously accepted
- GREEN: all 200 @cipherbox/crypto tests pass, including the
  uuid-acceptance.json oracle block

Entire-Checkpoint: 013c621b6186
- uuid_acceptance_cross_language drives build_node_aad over every
  uuid-acceptance.json case, asserting Ok for accept / Err for reject
- RED: current Uuid::parse_str over-accepts simple-32-hex, braced,
  and urn:uuid forms that the shared oracle marks reject

Entire-Checkpoint: 44cf5054c3fb
- is_canonical_uuid_form: dependency-free byte-position check for the
  8-4-4-4-12 hyphenated shape, applied before Uuid::parse_str
- rejects simple-32-hex, braced {...}, and urn:uuid:... forms that
  Uuid::parse_str previously accepted
- no regex/once_cell dependency added to crates/crypto/Cargo.toml
- GREEN: build_node_aad unit tests and cross_language tests pass,
  Rust and TS now produce identical accept/reject verdicts for every
  uuid-acceptance.json case

Entire-Checkpoint: c7ea0bac3b3d
- Extend decode_ipns_cbor_validity's return type to a tuple carrying
  Validity bytes plus an Option<i64> ValidityType placeholder
- Add tests asserting ValidityType 0/1 extraction and duplicate-key
  rejection; extraction not yet implemented so these fail (RED)
- Thread bind_verified's single call site through the new tuple shape
  (ValidityType value not yet consumed)

Entire-Checkpoint: ed32f9cc25f3
- Implement ValidityType extraction alongside Validity bytes, with
  duplicate-key rejection mirroring the existing Validity guard
- Returns Option<i64>: Some(n) when present and an integer, None when
  absent; the == 0 EOL gate is left to the caller (bind_verified,
  Task 2), this decoder only reports the value

Task 1 of 75-02 (Phase 75: cross-language IPNS/node-codec parity).

Entire-Checkpoint: e3dc7037318b
- Add tests asserting bind_verified rejects records with a missing or
  non-zero ValidityType, and still accepts/expires ValidityType-0
  records exactly as before
- Missing/non-zero-ValidityType tests fail (RED) since the gate is
  not yet implemented

Entire-Checkpoint: 3897451ec1c1
- bind_verified now fails closed on missing or non-zero ValidityType
  before treating Validity as an EOL/expiry timestamp (Phase 75
  gap #7 — Rust side; TS mirrors this in Plan 03)
- Widen bind_verified from pub(crate) to pub so crates/fuse's test
  target can call it directly (Task 3 dedups classify_vector onto it)
- parse_rfc3339_to_unix_secs and the 5-minute skew buffer are
  untouched

Task 2 of 75-02.

Entire-Checkpoint: 210682e3dc7b
- Replace classify_vector's hand-spelled cid/sequence binding block
  with a thin wrapper that calls the now-pub cipherbox_api_client
  bind_verified — deletes the duplicated binding logic that let
  gap #9 go undetected (D-07's expiry leg never got mirrored here)
- Bump the non-vacuous vector-count guard 8 -> 12 to match the
  4 new invalid cases landed by Plan 75-01 (expired, wrong-validity-
  type, and two malformed-RFC3339 sub-cases)
- All 12 cases now classify to their expected_result, including the
  4 new cases exercising the Task 2 ValidityType gate end-to-end

Task 3 of 75-02. SC1 (Rust half) met.

Entire-Checkpoint: f9c10ada7067
- Bump shared-vector count guard from 8 to 12 (Plan 01's 4 new invalid cases)
- Add 4 per-vector tests for expired-valid-sig, wrong-validity-type,
  malformed-rfc3339-trailing-component, malformed-rfc3339-impossible-date
- Add parseRfc3339ToUnixSecs unit tests mirroring the Rust parser's
  rejection branches (trailing components, impossible dates, non-digit
  fraction, missing Z)
- Add ValidityType absent/non-zero rejection assertions
- RED: fails against the current loose new Date(validityStr) parse and
  unread ValidityType field

Entire-Checkpoint: 86715bc90ed1
- Add parseRfc3339ToUnixSecs, a manual strict parser mirroring the Rust
  parse_rfc3339_to_unix_secs branch-for-branch (crates/api-client/src/ipns.rs):
  rejects trailing date/time components, impossible calendar dates
  (leap-aware), non-digit fractional seconds, and missing Z, without
  rolling an invalid date forward
- Replace new Date(validityStr).getTime() in resolveIpnsRecord with the
  strict parser; preserve the 5-minute skew buffer and expiry comparison
- Add a fail-closed cborFields['ValidityType'] === 0 gate before treating
  Validity as an expiry timestamp, mirroring Rust's bind_verified
  (T-75-07)
- TS and Rust now reject the same 12-case tests/vectors/ipns/verify.json
  fixture identically (SC1 TS half)

Entire-Checkpoint: 864bd5c6787d
Entire-Checkpoint: 36c3ccaf9bc2
FSM1 and others added 3 commits July 11, 2026 19:53
Phase 74 (merged PR #607) resolved these but the GSD auto-close under-closed
them, leaving them in pending despite resolves_phase: 74:
- deep-scope-exit rotation now refreshes ALL rotated_nodes inodes (grant_scope.rs)
- WinFsp rename gates the overwritten dest scope-exit (74-06, windows/write_ops.rs)
- query_grants_rooted_at is a real /shares/sent remint, not a no-op (74-07)

Verified each against the merged code + tests before moving; appended a
resolution note to each. No pending resolves_phase:74 todos remain.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Z3zThQZPm6bVk2476WURL
Entire-Checkpoint: 64ff86dfcd51
Phase 75 crypto/privacy review found the Rust and TS IPNS verifiers reach
different verdicts on some signed records. Closed the two material gaps on both
sides so they fail closed identically:

- Duplicate CBOR map keys: TS cborDecode defaulted to last-wins (a signed
  ValidityType:[1,0] decoded to 0 and was accepted) while Rust rejects
  duplicates. TS now decodes with rejectDuplicateMapKeys: true.
- RFC3339 fixed-width fields: Rust parse::<T>() accepted a leading +/- and
  overflowing years; TS did not enforce a 4-digit year. Both now use a
  fixed-width digit check (year 4, others 2), rejecting leading signs and
  non-canonical-width fields identically.

Locked with parser tests on both languages plus a duplicate-map-key integration
test. One LOW benign-direction divergence (CBOR float-0.0 ValidityType) is
deferred to a todo. Full report in .planning/security/REVIEW-2026-07-11-phase75-parity.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Z3zThQZPm6bVk2476WURL
Entire-Checkpoint: 42263fd885f8
CodeRabbit CLI review of the phase 75 branch surfaced a real SC3 soundness gap
plus test-rigor and bookkeeping items:

- uuidToBytes accepted a trailing-newline UUID because JS `$` (no `m` flag) also
  matches before a final "\n", while Rust is_canonical_uuid_form rejects it
  (bytes.len() != 36) — a cross-language divergence. Added a length === 36 guard
  and a "\n" regression case to the shared uuid-acceptance.json oracle (now run by
  both the TS and Rust oracle tests).
- Tightened the UUID-oracle reject assertions on both sides to require the specific
  INVALID_AAD_INPUT verdict, and made the TS loop fail loudly on an unknown expected
  value instead of silently treating it as a reject.
- Reconciled STATE.md metadata and banner-marked the pre-fix crypto review report so
  the SECURED verdict is unambiguous.

Verified: @cipherbox/crypto 200 passed; cipherbox-crypto cross_language 7 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Z3zThQZPm6bVk2476WURL
Entire-Checkpoint: e4e60b8860fd
@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@FSM1, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 46 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b8c6082c-e5e7-4059-8e9c-934cba29d6c1

📥 Commits

Reviewing files that changed from the base of the PR and between 2917c85 and 4379ffd.

📒 Files selected for processing (43)
  • .planning/PROJECT.md
  • .planning/ROADMAP.md
  • .planning/STATE.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-01-PLAN.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-01-SUMMARY.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-02-PLAN.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-02-SUMMARY.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-03-PLAN.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-03-SUMMARY.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-04-PLAN.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-04-SUMMARY.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-05-PLAN.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-05-SUMMARY.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-LEARNINGS.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-PATTERNS.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-RESEARCH.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-SECURITY.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-VALIDATION.md
  • .planning/phases/75-cross-language-ipns-and-node-codec-verification-parity/75-VERIFICATION.md
  • .planning/security/REVIEW-2026-07-11-phase75-parity.md
  • .planning/todos/completed/2026-06-24-harden-validity-type-and-vector-expiry-lockstep.md
  • .planning/todos/completed/2026-06-24-ts-resolve-strict-rfc3339-validity-parity.md
  • .planning/todos/completed/2026-06-28-harden-uuid-acceptance-parity-aad-builder.md
  • .planning/todos/completed/2026-07-07-node-codec-kat-pin-file-iv-encoding.md
  • .planning/todos/completed/2026-07-08-desktop-query-grants-rooted-at-remint-noop.md
  • .planning/todos/completed/2026-07-08-winfsp-d15d-gate-ordering-parity.md
  • .planning/todos/completed/2026-07-09-deep-scope-exit-rotation-refreshes-only-grant-root-inode-key.md
  • .planning/todos/pending/2026-07-11-ts-validitytype-float-vs-integer-cbor-parity.md
  • crates/api-client/src/ipns.rs
  • crates/core/src/ipns.rs
  • crates/core/tests/node_codec_vectors.rs
  • crates/crypto/src/aes.rs
  • crates/crypto/tests/cross_language.rs
  • crates/fuse/tests/ipns_verify_vectors.rs
  • packages/core/src/__tests__/node-codec-vectors.test.ts
  • packages/crypto/src/__tests__/build-node-aad.test.ts
  • packages/crypto/src/utils/encoding.ts
  • packages/sdk-core/src/__tests__/ipns.test.ts
  • packages/sdk-core/src/ipns/index.ts
  • scripts/gen-ipns-verify-vectors.ts
  • tests/vectors/crypto/uuid-acceptance.json
  • tests/vectors/ipns/verify.json
  • tests/vectors/node-codec.json
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cross-language-ipns-and-node-codec-verification-parity

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.

❤️ Share

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

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Z3zThQZPm6bVk2476WURL
Entire-Checkpoint: 01f9fb37c55b
@github-actions github-actions Bot added release:cipherbox-core:feat Minor version bump (new feature) for cipherbox-core release:core:feat Minor version bump (new feature) for core release:crypto:feat Minor version bump (new feature) for crypto release:cipherbox-crypto:feat Minor version bump (new feature) for cipherbox-crypto release:api:feat Minor version bump (new feature) for api release:sdk-core:feat Minor version bump (new feature) for sdk-core release:cipherbox-fuse:fix Patch version bump (bug fix) for cipherbox-fuse release:cipherbox-sdk:fix Patch version bump (bug fix) for cipherbox-sdk release:desktop:fix Patch version bump (bug fix) for desktop release:sdk:fix Patch version bump (bug fix) for sdk release:web:fix Patch version bump (bug fix) for web release:tee-worker:fix Patch version bump (bug fix) for tee-worker labels Jul 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Release Preview

Package Bump Label Source
api minor release:api:feat Direct (feat commit)
cipherbox-core minor release:cipherbox-core:feat Direct (feat commit)
cipherbox-crypto minor release:cipherbox-crypto:feat Direct (feat commit)
cipherbox-fuse patch release:cipherbox-fuse:fix Cascade (cipherbox-core minor)
cipherbox-sdk patch release:cipherbox-sdk:fix Cascade (cipherbox-core minor)
core minor release:core:feat Direct (feat commit)
crypto minor release:crypto:feat Direct (feat commit)
desktop minor release:desktop:fix Cascade (cipherbox-core minor)
sdk patch release:sdk:fix Cascade (core minor)
sdk-core minor release:sdk-core:feat Direct (feat commit)
tee-worker patch release:tee-worker:fix Cascade (core minor)
web minor release:web:fix Cascade (core minor)

Cascade Details

  • cipherbox-core minor -> cipherbox-fuse patch (direct dependency)
  • cipherbox-core minor -> cipherbox-sdk patch (direct dependency)
  • cipherbox-core minor -> desktop patch (direct dependency)
  • core minor -> sdk patch (direct dependency)
  • core minor -> web patch (direct dependency)
  • core minor -> tee-worker patch (direct dependency)

@greptile-apps

greptile-apps Bot commented Jul 11, 2026

Copy link
Copy Markdown

Greptile Summary

This PR aligns Rust and TypeScript verification behavior for IPNS records and node-codec vectors. The main changes are:

  • Strict IPNS ValidityType and RFC3339 expiry checks in both languages.
  • Duplicate CBOR map-key rejection in the TypeScript and Rust IPNS decode paths.
  • Canonical-only UUID handling for node AAD construction.
  • Base64-locked fileIv vector checks for node-codec parity.
  • Updated shared verification vectors and phase documentation.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
crates/core/src/ipns.rs Adds duplicate text-key rejection and ValidityType extraction for Rust IPNS CBOR decoding.
crates/api-client/src/ipns.rs Adds the Rust ValidityType gate and fixed-width RFC3339 parser used by verified IPNS resolve.
packages/sdk-core/src/ipns/index.ts Adds duplicate-key CBOR rejection plus strict ValidityType and RFC3339 checks in the TypeScript IPNS resolve path.
crates/crypto/src/aes.rs Tightens Rust node AAD UUID handling to canonical hyphenated UUIDs.
packages/crypto/src/utils/encoding.ts Tightens TypeScript UUID byte parsing to the same canonical UUID acceptance domain.

Reviews (2): Last reviewed commit: "fix(75): reject any duplicate CBOR key i..." | Re-trigger Greptile

Comment thread packages/sdk-core/src/ipns/index.ts
@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.70690% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.68%. Comparing base (2917c85) to head (4379ffd).

Files with missing lines Patch % Lines
crates/core/src/ipns.rs 97.95% 2 Missing ⚠️
crates/crypto/src/aes.rs 94.73% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #608      +/-   ##
==========================================
+ Coverage   70.16%   77.68%   +7.52%     
==========================================
  Files         157      197      +40     
  Lines       15425    32874   +17449     
  Branches     1952     1952              
==========================================
+ Hits        10823    25539   +14716     
- Misses       4348     7081    +2733     
  Partials      254      254              
Flag Coverage Δ
api 84.74% <100.00%> (+<0.01%) ⬆️
api-client 84.74% <100.00%> (+<0.01%) ⬆️
core 84.74% <100.00%> (+<0.01%) ⬆️
crypto 84.74% <100.00%> (+<0.01%) ⬆️
desktop 21.41% <ø> (-10.03%) ⬇️
rust 79.30% <98.68%> (?)
sdk 84.74% <100.00%> (+<0.01%) ⬆️
sdk-core 84.74% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
crates/api-client/src/ipns.rs 92.20% <100.00%> (ø)
packages/crypto/src/utils/encoding.ts 82.05% <100.00%> (+0.47%) ⬆️
crates/crypto/src/aes.rs 99.67% <94.73%> (ø)
crates/core/src/ipns.rs 97.46% <97.95%> (ø)

... and 94 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…arity

Greptile P1: the TS resolve fix (rejectDuplicateMapKeys: true) rejects a
duplicate of ANY key, but the Rust decoders only rejected duplicates of their
target fields (Value/Sequence, Validity/ValidityType). A signed record with a
duplicate ignored key like TTL was therefore Rust-accepts / TS-rejects — a new
parser-differential in the opposite direction.

decode_ipns_cbor_data and decode_ipns_cbor_validity now reject any duplicate
text map key via a seen-keys set, matching the TS decoder. Verified:
cipherbox-core 28 passed (incl. new dup-TTL test), api-client 25, fuse vectors 1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Z3zThQZPm6bVk2476WURL
Entire-Checkpoint: 1ef91f3a89ac
@FSM1
FSM1 merged commit 77e52cb into main Jul 11, 2026
30 checks passed
@FSM1
FSM1 deleted the feat/cross-language-ipns-and-node-codec-verification-parity branch July 11, 2026 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:api:feat Minor version bump (new feature) for api release:cipherbox-core:feat Minor version bump (new feature) for cipherbox-core release:cipherbox-crypto:feat Minor version bump (new feature) for cipherbox-crypto release:cipherbox-fuse:fix Patch version bump (bug fix) for cipherbox-fuse release:cipherbox-sdk:fix Patch version bump (bug fix) for cipherbox-sdk release:core:feat Minor version bump (new feature) for core release:crypto:feat Minor version bump (new feature) for crypto release:desktop:fix Patch version bump (bug fix) for desktop release:sdk:fix Patch version bump (bug fix) for sdk release:sdk-core:feat Minor version bump (new feature) for sdk-core release:tee-worker:fix Patch version bump (bug fix) for tee-worker release:web:fix Patch version bump (bug fix) for web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant