Skip to content

feat: noncanonical fixtures (PBNode field order) - #212

Merged
vmx merged 3 commits into
ipld:masterfrom
lidel:noncanonical-fixtures
Sep 9, 2026
Merged

feat: noncanonical fixtures (PBNode field order)#212
vmx merged 3 commits into
ipld:masterfrom
lidel:noncanonical-fixtures

Conversation

@lidel

@lidel lidel commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Problem

Review of ipld/ipld#383 asked for codec-fixtures coverage so implementations can verify they decode the opt-in Data-first PBNode order from IPIP-550. But positive fixtures here must round-trip byte-for-byte, and every encoder is canonical (Links-first), so a Data-first block can never live in fixtures/.

Fix

  • new noncanonical-fixtures/<codec>/decode/*.json category, mirroring negative-fixtures: decoding must succeed, match the canonical decode, and canonically re-encode to canonicalCid
  • first case: the Data-before-Links block from IPIP-550, paired with a new positive fixture dagpb_1namedlink+data holding the canonical twin of the same logical node (the block from feat: add data-first dag-pb block #211, under its canonical name)
  • all four runners (JS, Go, Rust, Python) learn the category; // TODOs note these can become full round-trip fixtures once codecs expose opt-in encoders like feat: allow encoding Data fields before Links in PBNode messages js-dag-pb#111
  • drive-by: removed a leftover describe.only in js/test.js that was skipping the entire positive suite in CI (JS leg now runs 219 tests, all green, as are Go, Rust, and Python)

cc @achingbrain as #211 may not be enough to be meaningful (protect from read-capability regressions)

@vmx does this look like a sensible way to wire up this style of fixture, so read-interop stays covered even while writes remain canonical (legacy behavior, no breaking changes, maximized interop of reads)?

New noncanonical-fixtures category for blocks that decode
successfully but are not in canonical form, so they cannot
round-trip byte-for-byte: runners assert decoding succeeds,
matches the canonical decode, and canonically re-encodes to
canonicalCid. First case: the dag-pb Data-before-Links order
from IPIP-550 (readers accept both orders, links-first stays
canonical), paired with positive fixture dagpb_1namedlink+data
holding the canonical twin.

- all four runners (js, go, rust, python) learn the category
- js/test.js: drop leftover describe.only that skipped the
  whole positive suite in CI

Refs ipfs/specs#550, ipld/ipld#383
Prevents text diffs and line-ending normalization (e.g. on
Windows checkouts) from corrupting byte-exact fixture payloads
whose CIDs must match their content.
@lidel
lidel marked this pull request as ready for review September 1, 2026 16:15

@vmx vmx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @lidel! I've reviewed everything except for the Go implementation and it looks good to me. @rvagg what do you think?

IPIP-550 no longer defines a profile; the field order is a
low-level opt-in.
@rvagg

rvagg commented Sep 8, 2026

Copy link
Copy Markdown
Member

seems fine to me

@vmx
vmx merged commit b676336 into ipld:master Sep 9, 2026
25 checks passed
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.

3 participants