Skip to content

Releases: flawme/varn

v0.3.0 — Field-report fixes + platform regression suite

Choose a tag to compare

@flawme flawme released this 01 Sep 19:58

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

Choose a tag to compare

@flawme flawme released this 31 Aug 19:03

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 755 script restored as 644. 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 flagsuchg (user immutable), hidden, and friends are captured via st_flags and restored via lchflags. 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 warnings clean
  • cargo fmt --check clean
  • CI green on ubuntu, macos, and windows (all platform code paths compile and test)
  • Live smoke tests: 755 mode drift restored to 755; 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

Choose a tag to compare

@flawme flawme released this 31 Aug 12:34

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 guardvarn init now creates .varn/.gitignore containing *. Git applies .gitignore files 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 warningvarn init and varn checkpoint warn (text and JSON warnings) when the store sits in a git work tree and is not excluded from git, with a copy-pasteable fix.
  • Guard backfillvarn migrate adds the missing guard to stores created before this release; --dry-run reports without writing.
  • install.sh — one-line installer: curl -fsSL https://raw.githubusercontent.com/flawme/varn/main/install.sh | sh
  • Checksums — every release publishes SHA256SUMS.txt plus per-asset .sha256 files.

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 warnings clean
  • cargo fmt --check clean
  • End-to-end smoke test: git status --porcelain shows no .varn entries 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

Choose a tag to compare

@flawme flawme released this 30 Aug 17:47

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
  • --json output 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.git

Or build from source — see INSTALL.md for details.

Verification

  • 272 tests pass
  • cargo fmt --check clean
  • cargo clippy -- -D warnings clean
  • cargo build --release clean
  • CI passing on Linux, macOS, and Windows