Refuse a backup destination an unplugged volume left empty (closes #239)
check / check (push) Waiting to run

Every backup writes vaultik-destination.txt at the destination root.
While the local index holds snapshots, a destination without it is
not present: snapshot create refuses before writing, prune and
snapshot purge fail, snapshot list and snapshot remove warn. remote
nuke deletes it last. The file:// backend no longer creates its
destination directory and checks for it on every write, which
protects a directory on a removable volume but not a mount point.

Tests back up into directories that exist; fixtures standing for a
written destination carry the marker, and two tests check they get
past it.

Judgement call: the marker is rewritten on every backup.
Deviation: for the complexity limit, snapshot name selection moved
into snapshotNamesToCreate and the --force/--json test into
confirmRemoveSnapshot, both unchanged.

Model: opus-5-5
This commit is contained in:
2026-10-13 23:42:41 +00:00
parent dd3667c8e9
commit aae82914ed
41 changed files with 591 additions and 114 deletions
+6 -1
View File
@@ -4,7 +4,7 @@ This document describes the structure and organization of data stored in the S3
## Overview
Vaultik stores all backup data in an S3-compatible object store. The repository consists of two main components:
Vaultik stores all backup data in an S3-compatible object store. The repository consists of two main components, plus a marker file:
1. **Blobs** - The actual backup data (content-addressed, encrypted)
2. **Metadata** - Snapshot information and manifests (partially encrypted)
@@ -12,6 +12,7 @@ Vaultik stores all backup data in an S3-compatible object store. The repository
```
<bucket>/<prefix>/
├── vaultik-destination.txt
├── blobs/
│ └── <hash[0:2]>/
│ └── <hash[2:4]>/
@@ -24,6 +25,10 @@ Vaultik stores all backup data in an S3-compatible object store. The repository
The metadata subdirectory is named with the **remote key**, a one-way hash of the snapshot ID, not with the human-readable snapshot ID itself. See [Remote Key Derivation](#remote-key-derivation).
## Marker File (`vaultik-destination.txt`)
Every backup writes this file at the root before it uploads anything. It holds one fixed line of plain text and names no host, path or time. While the local index holds snapshots, a destination without it is treated as not present: `snapshot create` refuses to write to it, and `prune`, `snapshot purge`, `snapshot remove` and `snapshot list` behave as for a destination that cannot be listed. An unplugged volume leaves an empty directory at its mount point, and without the marker that directory would read as a destination whose snapshots are all gone. `remote nuke` deletes the marker last.
## Blobs Directory (`blobs/`)
### Structure