Commit Graph
12 Commits
Author SHA1 Message Date
Andy DixonandClaude Sonnet 5.5 92ff8546fd Document mirror, migrate and the man pages in the README
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
0.3
2026-09-29 18:43:16 +01:00
Andy DixonandClaude Sonnet 5.5 0b3dcf08f2 Add man pages for vault and every command
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 15:04:28 +01:00
Andy DixonandClaude Sonnet 5.5 10f2a88493 Add a mirror command that crawls a site into the vault
Single-threaded, same host only, Chrome user agent. Links in HTML and
CSS are rewritten to relative paths. Includes a man page and a guide note.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 15:02:12 +01:00
Andy DixonandClaude Opus 5.5 e40a803367 Re-shoot the guide's screenshots and add one for migrate
shots.py gains a pseudo-terminal runner so it can answer migrate's
overwrite question, and the guide shows the resulting screenshot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
0.2
2026-09-28 16:36:12 +01:00
Andy DixonandClaude Opus 5.5 eb138b5524 Add URLs to add, and a migrate command that deletes originals
add now downloads http(s) URLs (with a Chrome user agent) through a
private temporary file, and treats ".", ".." and "/" as "this folder's
contents" so the destination folder is no longer dropped for "..".

migrate is add followed by deleting each original and any directories
left empty. It asks on the terminal before overwriting anything already
in the vault, refusing when there is no terminal, unless --yes is given.

Adding or migrating a directory skips the vault and key file if they
live inside it, so migrate can never ingest or delete them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:59:09 +01:00
Andy DixonandClaude Opus 5.5 8b7a7f1415 Take the guide's cover version from release tags only
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
0.1
2026-09-26 18:21:11 +01:00
Andy DixonandClaude Opus 5.5 eea16c9076 Chunk objects, shard the store, and make filler configurable
File bodies are now cut into 4 MiB objects, the last padded to its
power-of-two bucket, so every object is 64 KiB to 4 MiB whatever the file
size. Object IDs are HMAC'd from a secret per-record seed, so nothing on
disk links a file's pieces, and each object still leads with its own ID,
binding it to its record and position. Chunks are encrypted and synced by
a small worker pool so their fsyncs overlap.

records/ and objects/ are sharded into 256 subdirectories by ID prefix,
all created at init, with every shard's mtime pinned to the epoch.

vault init --filler SIZE writes at least SIZE of filler. Filler entries
are now real entries for a throwaway key, of log-uniform random sizes, so
they carry multi-chunk files like a real collection.

The marker becomes VAULT 2; earlier vaults are not supported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 18:20:51 +01:00
Andy Dixon 8f3a755bf9 Doc fix 2026-09-26 15:23:21 +01:00
Andy Dixon 81dc29097f Add the illustrated user guide
A LaTeX field guide covering install, keys, everyday commands, the
decoy passphrase, scripting, locking and sync, internals, troubleshooting
and a cheat sheet. build-pdf.sh compiles it with a pinned Tectonic,
downloaded on first use. shots.py regenerates every screenshot from the
real vault binary in a sandbox home.
2026-09-26 15:01:35 +01:00
Andy Dixon 5aa60d7bc7 Add vault locking and a cross-platform build script
Commands that change the vault hold an exclusive lock on DIR/.lock and
readers hold a shared one, taken after the passphrase prompt. A blocked
process says it is waiting. Unix uses fcntl locks and Windows uses
LockFileEx, both released by the OS if the process dies. Plan 9 and
WebAssembly fall back to an exclusive lock file.

build.sh cross-compiles static binaries for every Go target that builds
without cgo (43 today, armv6 and armv7 for 32-bit ARM Linux) and writes
SHA256SUMS.
2026-09-26 14:36:44 +01:00
Andy Dixon be09659f8f Add decoy passphrase
genkey optionally takes a second passphrase that unlocks a separate
decoy identity. Every command run with it sees and changes only decoy
files; records sealed to the other key are skipped silently.

The key file always carries two equal-size slots in random order, with
random bytes in an unused slot, and both slots are always tried. init
seeds each vault with 8-32 entries sealed to a discarded key, so real
files are indistinguishable from filler to a decoy-only holder.
2026-09-26 14:06:54 +01:00
Andy Dixon d95f2d04a4 Initial vault: single-binary post-quantum file vault
Strip Fury back to its vault functionality in one `vault` command:
genkey, init, add (file or directory, optional folder inside the vault),
list, get, mv and rm.

The hybrid FrodoKEM-640 + ML-KEM-768 encryption core is kept under
internal/pqcrypt. Signing, policies, profiles, backups, SSH remotes,
FIDO2, agents, provenance and compression are removed.
2026-09-26 14:05:10 +01:00