Releases: flawme/varn
Release list
v0.3.0 — Field-report fixes + platform regression suite
Every bug from the v0.2.0 Windows field report is fixed, plus five more found by the new regression suite during CI hardening. Each fix has a permanent named regression test.
Critical fixes
- Stale scan cache → wrong-content restores — the cache keyed on (size, mtime-seconds); two same-size writes within one second reused the first content's hash, and restore silently returned OLD data while verification passed. The cache now keys on sub-second mtime, and checkpoint self-heals: a hash that doesn't match the file's actual content discards the cache and re-scans.
- Read-only files broke every re-restore (os error 5) — restore now clears read-only/hidden/system attributes (and Unix write-protect bits) before overwriting or deleting, then re-applies the checkpoint's attributes.
- mtime restore failures were silent — SetFileTime after the readonly attribute was applied failed and was swallowed, so verification failed ~50% of the time. mtime is applied before protection attributes; failures are warnings.
Also fixed
- Checkpoint IDs deterministic — the ID hashed the creation timestamp, breaking the documented idempotency contract. IDs are now a pure function of description + root + state.
- Unhashable files poisoned checkpoints — locked files were stored with an empty hash and could never be restored. Now skipped with a warning.
.git/internals were checkpointed — the scanner skips.git/at any depth.- Windows ACL restore always failed (os error 87) — three bugs: NUL-padded SDDL strings, SetNamedSecurityInfoW handed the whole security descriptor as the DACL, and owner/group flags set with null pointers. ACL (DACL) restore now works.
- diff reported every restored file as Modified on Windows — the re-captured SDDL legitimately differs (inherited ACEs merged), so ACL is excluded from diff's metadata comparison.
- Restore was not transactional under locks — a pre-flight probe checks every overwrite/delete target first; it is layout-aware and clears write-protection before probing (protection is not a lock).
- Ignore-rule changes caused phantom diffs — diff/restore treat the checkpoint as a self-contained state under its own rules.
- migrate accepted newer repositories — now errors with an upgrade hint.
- Concurrency races — temp-file collisions in the object store, scan cache, and snapshot saves (PID-only names); all use unique names per write.
- Path-safety guard covered only hashed entries — hashless entries with absolute/traversing paths are now rejected too.
New: platform regression suite
tests/regression/ — 135+ named tests organized by platform (common/, windows/, macos/, linux/). 442 tests total, run on all three CI platforms every commit.
Platform support
Linux and Windows are officially tested (CI matrix + field testing). macOS runs the same CI suite and shares the Unix code paths with Linux — substantially equivalent coverage.
Full changelog: https://github.com/flawme/varn/blob/master/CHANGELOG.md
v0.2.0 — Cross-platform metadata parity
Varn now captures and restores the same classes of filesystem state on Linux, macOS, and Windows. No more second-class Windows support.
What's new
- Full Unix permission mode — rwx bits plus setuid/setgid/sticky are captured on Linux/macOS and fully restored. Previously only the readonly bit was restored; a
755script restored as644. Older snapshots without a captured mode fall back to the old readonly behavior. - Windows file attributes — READONLY, HIDDEN, SYSTEM, ARCHIVE are captured and restored via
SetFileAttributesW. - macOS BSD file flags —
uchg(user immutable),hidden, and friends are captured viast_flagsand restored vialchflags. Privileged flags are skipped with a warning rather than failing the restore (borg's best-effort practice). - Windows hard links — detected via
GetFileInformationByHandle(NTFS link counts) and restored as real hard links. Previously Windows restored hard-linked files as independent copies, silently breaking the link relationship. - Windows security descriptors — owner, group, and DACL are captured in SDDL form and restored via
SetNamedSecurityInfoW, best-effort with warnings (the restic/rsync approach). - Directory metadata restored correctly — creating/deleting children updates a directory's own mtime, so restore now applies directory metadata in a post-order pass (deepest first) after all child operations. Previously a restored directory mtime could be silently clobbered and verification would fail.
- Metadata drift detection — restore plans metadata-only updates when mode/flags/attributes/ACL differ but content is unchanged.
- Honest verification — post-restore verification checks the new metadata fields, so a failed mode or mtime restore is reported instead of silently passing.
Upgrade notes
No storage-format migration needed: the new fields are optional with serde defaults, so snapshots written by 0.1.x load unchanged. New checkpoints simply capture more.
New target-gated dependencies, pinned to exact versions (windows-sys =0.59.0, libc =0.2.189) so a fresh cargo update cannot silently pull an API-incompatible 0.x minor. Linux builds gain no new dependencies.
Verification
- 306 tests passing (
cargo test), including deterministic directory-mtime regression tests and snapshot backward-compatibility tests cargo clippy --all-targets --all-features -- -D warningscleancargo fmt --checkclean- CI green on ubuntu, macos, and windows (all platform code paths compile and test)
- Live smoke tests:
755mode drift restored to755; directory mtime restored to a fixed 2001 timestamp after child create/delete
Full changelog: https://github.com/flawme/varn/blob/master/CHANGELOG.md
v0.1.1 — Git coexistence guard
Varn now protects its own object store from accidental git staging.
The problem this fixes
.varn/ holds tens of thousands of content objects. If your project is also a git repository, a blind git add -A staged the entire store — a real workflow accident, and an easy one to hit.
What's new
- Automatic store guard —
varn initnow creates.varn/.gitignorecontaining*. Git applies.gitignorefiles to their own directory and below, so the whole store is ignored without Varn touching anything outside.varn/. varn init --gitignore— optionally adds.varn/to the enclosing repository's root.gitignore(created if missing, idempotent, fails with an actionable error outside a git repo).- Legacy store warning —
varn initandvarn checkpointwarn (text and JSONwarnings) when the store sits in a git work tree and is not excluded from git, with a copy-pasteable fix. - Guard backfill —
varn migrateadds the missing guard to stores created before this release;--dry-runreports without writing. - install.sh — one-line installer:
curl -fsSL https://raw.githubusercontent.com/flawme/varn/main/install.sh | sh - Checksums — every release publishes
SHA256SUMS.txtplus per-asset.sha256files.
Upgrade notes
Existing stores: run varn migrate once to add the guard. No storage-format change; checkpoints remain fully compatible.
Verification
- 298 tests passing (
cargo test) cargo clippy --all-targets --all-features -- -D warningscleancargo fmt --checkclean- End-to-end smoke test:
git status --porcelainshows no.varnentries in a Varn-managed git repository
Full changelog: https://github.com/flawme/varn/blob/master/CHANGELOG.md
Varn v0.1.0 — Local State Checkpointing & Rollback
What is Varn?
Varn captures a known state of your local filesystem, lets you observe what changed, and safely restores a previous state. It is designed for AI agents and automated tools operating on a local machine, but is equally useful for humans who want to safely experiment with local changes.
An automated process changed my local environment. What exactly changed, and can I safely return to the previous state?
Commands
varn init [path] Initialize Varn in a directory
varn checkpoint <desc> Capture the current filesystem state
varn list Display available checkpoints
varn diff <checkpoint> Compare current state with a checkpoint
varn restore <checkpoint> Restore a checkpoint
varn gc Remove unreferenced objects from the store
varn migrate Migrate storage format to current version
varn --json <command> Emit machine-readable JSON output
Features
- Content-addressed storage with SHA-256 hashing and deduplication
- Symlink scanning and full restoration
- Hard link detection and restoration (Unix)
- Permission, mtime, and uid/gid restoration (Unix)
- Conflict detection with explicit confirmation
- Safety checkpoint before restore (undo a bad restore)
- Idempotent checkpointing (same state = same ID, no duplicates)
- Incremental scanning with persistent mtime/size cache
- Content streaming for large files (no full file in memory)
- Ignore patterns via
.varnignore(gitignore-style syntax) - Storage format migration framework
- Garbage collection with
--dry-run --jsonoutput for AI agent integration- Linux, macOS, and Windows support
Security
- Path traversal prevention in restore paths
- Symlink escape prevention (CVE-2026-71556 / GHSA-9qw7-j9xw-fv9c class)
- Hard link target symlink bypass prevention (CVE-2026-32232 / ZeptoClaw R3)
- Object content hash verification before writing
- Predictable temp file name mitigation (process-ID suffix)
- Scan cache integrity (versioned, advisory-only trust model)
- Pre-flight object check prevents partial restores
- Full metadata verification in post-restore check
Installation
cargo install --git https://github.com/flawme/varn.gitOr build from source — see INSTALL.md for details.
Verification
- 272 tests pass
cargo fmt --checkcleancargo clippy -- -D warningscleancargo build --releaseclean- CI passing on Linux, macOS, and Windows