> **RULE: Never add Co-Authored-By or any AI attribution to commits. Ever.**
# znippy workspace
## Local environment
| Path | Drive | Purpose |
|------|-------|---------|
| `~/work/` | NVMe SSD (938G) | fast working area — use for znippy output, bench temp files, cargo target |
| `/run/media/rickard/T9/` | HDD (3.7T) | large storage |
| `/run/media/rickard/T9/planet-260427.osm.bz2` | HDD | OSM planet dump 2026-04-27 — reference input for osm-katana benchmarks |
| `/run/media/rickard/T9/osm-out/` | HDD | OSM benchmark output and intermediate files |
| `/run/media/rickard/T9/airgap/` | HDD | holger airgap test data (see holger WORKSPACE.md) |
Run benchmarks with output going to `~/work/` to avoid thrashing the HDD.
OSM benchmark inputs read from T9 (sequential, HDD is fine for large reads).
## Dependency graph
```
znippy-zoomies/linflate (DEFLATE core)
├── znippy-zoomies/lgz (gzip)
├── znippy-zoomies/ljar (JAR/ZIP)
└── znippy-zoomies/lzip-parallel (ZIP)
znippy-zoomies/ldeflate (DEFLATE write side; owns the already-compressed probe)
└── znippy-common (re-exports it as znippy_common::precompressed)
znippy-zoomies/lbzip2 (bzip2, independent)
znippy-zoomies/zstd-sys-rs (zstd FFI, independent)
znippy-zoomies/osm-katana (OSM→GeoParquet/PBF, uses lgz + lbzip2 + zstd-sys-rs)
znippy-zoomies (fast primitives: OSM index, gatling, psort)
znippy-common / znippy-compress / znippy-decompress / znippy
znippy-plugin-maven (uses ljar)
znippy-plugin-python (uses lzip-parallel)
znippy-cli
```
## Release gate protocol
Before `cargo publish` for any crate:
1. Run benchmarks: `cargo bench -p <crate>`
2. Compare result against crate's `bench_history.json` — no result may drop >10% vs last entry for same machine
3. If valid: append result to `bench_history.json`, commit, `git tag vX.Y.Z`, `cargo publish`
## Publish order (when linflate changes, cascade)
**`ldeflate` is not on crates.io yet** (index.crates.io has no `ld/ef/ldeflate`,
checked 2026-08-03) and `znippy-common` now depends on it, so `cargo publish -p
znippy-common` will fail until `ldeflate 0.1.0` is published. It is a leaf —
gatling/rotaryengine, flate2, anyhow — so it can go up at any time, ahead of the
znippy cascade below.
```
ldeflate → znippy-common → … (the probe's home; publish first)
linflate → lgz, ljar, lzip-parallel → znippy-zoomies → osm-katana
→ znippy-plugin-maven
→ znippy-plugin-python
→ znippy
```
## Benchmark history files
| Crate | File |
|---------------|---------------------------------------------------|
| znippy | bench_history.json |
| osm-katana | znippy-zoomies/osm-katana/bench_history.json |
| lbzip2 | znippy-zoomies/lbzip2/bench_history.json |
| ljar | znippy-zoomies/ljar/bench_history.json |
| lzip-parallel | znippy-zoomies/lzip-parallel/bench_history.json |
| lgz | znippy-zoomies/lgz/bench_history.json |
## Benchmark column schema — decompressors
Each entry must include `reference_mbs`, `single_core_mbs`, and `multi_core_mbs`
so the two axes of improvement (pure-Rust vs C, single-core vs parallel) are always visible.
```json
{
"date": "2026-05-30",
"version": "0.3.2",
"crate": "lgz",
"machine": "Ryzen 9 7900",
"cores": 12,
"results": [
{
"name": "test_500mb_gz",
"input_mb": 500,
"reference_tool": "gzip -d",
"reference_mbs": 120.5,
"single_core_mbs": 185.3,
"multi_core_mbs": 2840.2,
"cores_used": 12
}
]
}
```
- `reference_mbs` — system tool, single-threaded (gzip/bzip2/unzip baseline)
- `single_core_mbs` — this crate, 1 thread (pure-Rust advantage over reference)
- `multi_core_mbs` — this crate, all cores (parallel advantage on top)
## Benchmark column schema — osm-katana
Same three-column principle; reference tool is typically `bzip2 -d | osmconvert` or `osmium`.
```json
{
"name": "liechtenstein_bz2_to_geo",
"input_format": "bz2",
"input_mb": 5.2,
"reference_tool": "bzip2 -d | osmconvert",
"reference_mbs": 8.5,
"single_core_mbs": 14.2,
"multi_core_mbs": 95.0,
"cores_used": 16
}
```
## Contracts
### decompressors → znippy-plugin-maven
- `ljar`: parallel JAR decompression, feature `host-decompressors`
### decompressors → znippy-plugin-python
- `lzip-parallel`: parallel ZIP decompression, feature `host-decompressors`
### decompressors → osm-katana
- `lgz`: gzip OSM input
- `lbzip2`: bzip2 OSM input (most common distribution format)
- `zstd-sys-rs`: zstd OSM input
## Doc update rule at release
At every release, **before** tagging:
- `CLAUDE.md` — update architecture sections if code changed
- `README.md` — update the headline number and benchmark table to current version; move the previous entry to a `## Benchmark history` section at the bottom (append, never overwrite history)
- `bench_history.json` — append new result line (never edit existing lines)
README.md structure:
```
# znippy
<3-line description>
**<best number> · <cores> cores · v<version>**
<benchmark table — current version only>
## Benchmark history
| version | date | best number | machine |
```