COOLJAPAN
← All posts

OxiH5 0.2.2 Released — 44 Agents, 33 Conformance Defects, and Every File Now Verified Against h5py and netCDF4-python

OxiH5 0.2.2 ships a 44-agent interop audit against h5py 3.16 and netCDF4-python 1.7.4, fixing 33 conformance defects and closing 9 writer gaps — shuffle/Fletcher32 pipelines, custom fill values, true netCDF coordinate variables. 862 tests passing — the sovereign scientific-data layer for COOLJAPAN.

release oxih5 pure-rust cooljapan noffi hdf5 netcdf scientific-data interop

Forty-four agents. Thirty-three distinct ways libhdf5 or netCDF-C rejected, misread, or crashed on a file OxiH5’s own reader had happily accepted as fine. Every one of them is fixed.

Today we released OxiH5 0.2.2 — the release where every file FileWriter and NcFileWriter produce is verified byte-openable by h5py 3.16 (libhdf5 2.0.0) and netCDF4-python 1.7.4, not merely by OxiH5’s own reader. That distinction matters: a reader that only ever checks its own writer’s output can mask an entire class of defects, and 0.2.2 exists because that’s exactly what had been happening.

No libhdf5. No FFI. No -sys crates. OxiH5 parses and writes the real HDF5 binary format — superblock, object headers, B-trees, heaps, the global heap, the filter pipeline, all eleven datatype classes — using nothing but std. #![forbid(unsafe_code)] guards oxih5-core; the facade crate carries exactly one documented unsafe block, the mmap call behind open_mmap. It compiles to a single static binary, needs no system libraries and no C toolchain at build time, and stays WASM-friendly by construction.

Why OxiH5 0.2.2 is a game changer

0.2.1 fixed the write path’s own internal correctness — chunk B-trees, group symbol tables, layout-v4 decoding. 0.2.2 asked a harder question: does the reference implementation agree these files are valid at all? A 44-agent differential interop audit answered it — each agent wrote a permutation of datatype, layout, filter and attribute, opened the result with both h5py and netCDF4-python, and bisected every divergence down to a minimal reproducer. The audit surfaced 33 confirmed conformance defects and 19 capability gaps no amount of self-consistency testing had caught:

OxiH5 0.2.2 ends all of that — and closes 9 of the 19 capability gaps the same audit surfaced:

Technical Deep Dive: how a differential audit finds what a reader can’t

  1. The harness never trusts OxiH5’s own reader as the oracle. Each of the 44 agents built a file through FileWriter/NcFileWriter, then handed it to h5py and netCDF4-python — real, independently-implemented parsers — and treated any exception, wrong value, or crash as a confirmed defect, bisected to the smallest input that reproduces it. A defect that both OxiH5’s reader and its writer agree on is invisible to self-consistency testing by construction; this is the only harness shape that catches it.
  2. Global heap conformance, four bugs deep. H5HG_MINSIZE = 4096 is a hidden libhdf5 precondition, not a documented format rule — collections are now floored at 4096, rounded to a power of two, capped at 65536; the free-space padding is a real index-0 object spanning the remainder; the object index is 32-bit throughout; vlen-string lengths are stored raw at strlen instead of strlen + 1.
  3. The global heap reader had its own alignment bug, found by the same audit. Multi-object collections at a file offset not 8-byte-aligned to the file dropped every object past the first — libhdf5 aligns each object relative to the collection start, not the file; netCDF-C routinely places a GCOL at an address like 4763, which the old code silently mishandled.
  4. DIMENSION_LIST’s datatype was wrong, not just its values. netCDF’s dimension-linkage attribute is a variable-length array of object references (H5T_VLEN{H5T_REFERENCE}) — a nested vlen-of-reference type distinct from a flat reference array. Writing the flat form parses as something structurally different, which is exactly the shape of bug that only crashes on the code path that assumes the correct encoding.

Getting Started

cargo add oxih5
use oxih5::FileWriter;

let path = std::env::temp_dir().join("out.h5");
let mut w = FileWriter::new();

// New in 0.2.2: shuffle -> deflate -> fletcher32 compose in one real pipeline.
w.write_dataset_f64("/sensors/temperature", &[21.5, 21.6, 21.4, 21.7], &[4])?;
w.set_shuffle("/sensors/temperature")?;
w.set_deflate("/sensors/temperature", 6)?;
w.set_fletcher32("/sensors/temperature")?;

// New in 0.2.2: a real fill value instead of the always-zero default.
w.write_dataset_i32("/sensors/status", &[0, 1, 0, 1], &[4])?;
w.set_fill_value_i32("/sensors/status", -1)?;

// New in 0.2.2: numpy-compatible boolean datasets.
w.write_dataset_bool("/sensors/active", &[true, true, false, true], &[4])?;

w.build(&path)?;
# Ok::<(), oxih5::OxiH5Error>(())

What’s New in 0.2.2

Tips

This is the foundation

OxiH5 belongs to NoFFI — the COOLJAPAN initiative retiring every C/C++/Fortran/-sys FFI dependency in the Rust ecosystem with a clean, memory-safe, Pure-Rust implementation. It already has real consumers pinned at 0.2.2 across the workspace:

Repository: https://github.com/cool-japan/oxih5

Star the repo ⭐ if “passes our own tests” shouldn’t be the bar for a file format library — the reference implementation’s opinion should be.

The era of a Pure-Rust writer whose correctness claim rested on its own reader is over. Pure Rust HDF5 that libhdf5 and netCDF-C actually agree on — that’s 0.2.2.

KitaSan at COOLJAPAN OÜ July 22, 2026

↑ Back to all posts