Quickstart
Pack & unpack
Target inferred from extension; primary + parity, hashed throughout. Grab a binary below or cargo run -p tx-cli --.
tx-cli pack /data backup.tx
tx-cli unpack backup.tx ./restore
Inspect & verify
List members, check hashes/Merkle + signatures, see stats.
tx-cli list -l backup.tx
tx-cli verify backup.tx
tx-cli stats --json backup.tx
Sign & trust
Ed25519 keys; verification is fail-closed once a trust store exists.
tx-cli gen-key ~/.tx/key
tx-cli pack /data backup.tx --sign-key ~/.tx/key
tx-cli trust add <pubkey>
Pack ISO
Index (index.idx) embedded and sorted first on disk.
tx-cli pack /data image.iso
Features
Resilience
Primary + redundancy, Merkle + hashes, trustable signatures.
- Tar → zstd → shards (parity by default) or full backup, hashed & signed.
- Tar-compatible:
.txstarts with.tx/manifest.jsonas the first tar entry, then the payload and shards/backup;tar xfstill works. - Optional Ed25519 signatures; trust-store enforcement.
ISO Path
Index-first images with manifest embedded.
- Staging copy with
index.idx+iso-manifest.json. - mkisofs/genisoimage/xorriso/xorrisofs places index first.
- Mount directly; no sidecars.
Signing
Passphrase and ssh-agent friendly.
export TX_SIGN_KEY=~/.ssh/colossus
export TX_SIGN_PASSPHRASE='hunter42' # if encrypted
export TX_SIGN_USE_AGENT=1 # prefer ssh-agent if loaded
Recovery Modes
Archive vs. file-aware repair.
- Default parity: per-group shards (small files grouped, large files per group) → repair individual groups/files with ~25–30% overhead.
--duplicate: full backup blob (larger, simpler) → whole-archive recovery if primary is bad.- Plain tar fallback:
tx unpackalso extracts.tar/.tgz/.tbz2/.tzstwhen no TX metadata is present (no verification).
Tar surface
The everyday bsdtar flags, covered.
list/-l,--strip-components,--exclude,--pathinclude.- stdin/stdout (
-),-vverbose,--files-from/-T. - Codec autodetect by magic (gzip/bzip2/zstd/xz), with a decompression-bomb cap.
Sparse files
Holes never touch RAM or disk.
- Pack emits real GNU sparse entries via
SEEK_DATA/SEEK_HOLE. - A 200 MB sparse image packs at ~20 MB RSS, not 200.
- Unpack re-punches holes (
--sparse), verified by block count.
Incremental & append
Snapshots and in-place edits.
--listed-incrementalsnapshots (path/mtime/size); deletions replayed on restore.append/updatereconstruct, merge by path, re-pack and re-sign.
Metadata
Preserved end to end.
- perms + mtime by default; ownership via
--preserve-owner. - xattrs / ACLs / SELinux as
SCHILY.xattr.*PAX records. - POSIX special files (FIFO, char/block devices).
Streaming
RAM-bounded packing.
- Tar spools to a temp file; parity shards stream to disk one group at a time.
- A 1 GB pack runs in ~8 MB RSS (was 2.4 GB).
Trust & safety
Fail-closed by construction.
- Verifier recomputes the Merkle root from hashes; a transplanted signature is rejected.
- Unsigned archives rejected when a trust store is configured.
- Bounded allocations + a 64 GiB decompressed backstop; zip-slip guarded.
TX vs PAR2
How it differs.
- TX is tar-compatible (
tar xf *.txworks); PAR2 is a sidecar over files/tars. - TX stores manifest/hashes/signatures inside the archive; PAR2 does not sign.
- TX parity defaults to per-group shards; PAR2 parity is per-file/chunk across multiple files.
- TX is one artifact (metadata+data); PAR2 requires managing
.par2sets separately.
TX vs 7zip
Format & trust differences.
- TX is tar-compatible (
tar xfworks); 7zip is its own container. - TX embeds manifest/hashes/signatures; 7zip has checksums but no signing.
- TX has built-in parity; 7zip needs external parity.
- TX is one artifact (metadata+data); 7zip often paired with sidecar parity.
Layout
Inside .tx
- Front: uncompressed tar so
tar xfworks. - Metadata:
.tx/manifest.jsonis the first entry (hashes, signatures, group map); tar users see it upfront. - Data:
.tx/groups/<gid>/shard.N.bin(parity mode) or.tx/backup.tar.zst(duplicate mode).
Pipeline
TX Pack
walk → tar → zstd → hash/merkle → optional sign → write primary+backup.
ISO Pack
stage → index/manifest → mkisofs sorted so index is first track.
Unpack
verify manifest/signatures → validate hashes → fallback to backup → untar.
Platforms
Linux
Native and musl.
cargo build --release
CC_x86_64_unknown_linux_musl=musl-gcc \
cargo build --release --target x86_64-unknown-linux-musl
Windows
MinGW toolchain required.
CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc \
cargo build --release --target x86_64-pc-windows-gnu
macOS
Build on macOS or with Apple SDK/clang (osxcross).
cargo build --release --target x86_64-apple-darwin
Downloads
Linux
- tx-cli-linux-amd64 — x86_64, static musl
- tx-cli-linux-arm64 — aarch64, static musl
macOS
- tx-cli-macos-arm64 — Apple silicon
- tx-cli-macos-amd64 — Intel
Windows
- tx-cli-windows-amd64.exe — x86_64
v0.0.6 · verify against SHA256SUMS · release notes
curl -O https://tx.itys.net/releases/v0.0.6/SHA256SUMS
sha256sum -c SHA256SUMS --ignore-missing
chmod +x tx-cli-linux-amd64 && ./tx-cli-linux-amd64 --help
Test Battery
63 tests green: the Rust suite plus a shell loop that pauses between suites so you can watch output.
cargo test # unit + integration (63 tests)
./scripts/test.sh # continuous, watchable loop
Covers pack/unpack round-trip, backup failover, destructive corruptions, signature forgery + fail-closed trust, decompression-bomb and zip-slip guards, sparse + incremental, and CLI smoke.