Move documents to docs/ and the example config to configs/ (closes #411)
check / check (push) Successful in 16m18s

ARCHITECTURE.md and TODO.md move to docs/, config.example.yml to
configs/, as REPO_POLICIES.md asks of the root. Links, the
no-snapshots error message and the example-config test follow them.

Model: opus-5-5
This commit is contained in:
sneak committed 2026-11-10 21:38:48 +00:00
1 parent 38b588f658
commit fdeec22de7
7 files changed
+18 -13

No files matched your search

+3 -3
View File
@@ -599,7 +599,7 @@ both are set.
For an implementation-level view of the internals — the data model, the `fx` For an implementation-level view of the internals — the data model, the `fx`
dependency-injection wiring, and the scanner — see dependency-injection wiring, and the scanner — see
[`ARCHITECTURE.md`](ARCHITECTURE.md). [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).
### remote storage layout ### remote storage layout
@@ -718,8 +718,8 @@ format does and does not protect.
## configuration reference ## configuration reference
Run `vaultik config init` to generate a fully commented config file; a complete Run `vaultik config init` to generate a fully commented config file; a complete
annotated example also lives in [`config.example.yml`](config.example.yml). Key annotated example also lives in
fields: [`configs/config.example.yml`](configs/config.example.yml). Key fields:
| Field | Default | Description | | Field | Default | Description |
| -------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | -------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
File renamed without changes.
+3 -3
View File
@@ -95,7 +95,7 @@ chunks:
- `ID`: UUID assigned at creation - `ID`: UUID assigned at creation
- `Hash`: `hex(SHA256(SHA256(uncompressed blob contents)))`, computed before - `Hash`: `hex(SHA256(SHA256(uncompressed blob contents)))`, computed before
compression and encryption (see compression and encryption (see
[docs/REPOSTRUCTURE.md](docs/REPOSTRUCTURE.md#blobs-directory-blobs)) [docs/REPOSTRUCTURE.md](REPOSTRUCTURE.md#blobs-directory-blobs))
- `UncompressedSize`: Total raw chunk data before compression - `UncompressedSize`: Total raw chunk data before compression
- `CompressedSize`: Size after zstd compression and age encryption - `CompressedSize`: Size after zstd compression and age encryption
- `CreatedTS`, `FinishedTS`, `UploadedTS`: Lifecycle timestamps - `CreatedTS`, `FinishedTS`, `UploadedTS`: Lifecycle timestamps
@@ -467,14 +467,14 @@ unplugged volume's empty mount point for a destination whose snapshots are all
gone. When the look-up fails for any reason other than not found, for example gone. When the look-up fails for any reason other than not found, for example
when S3 refuses it to credentials that allow only PUT, the check is skipped, so when S3 refuses it to credentials that allow only PUT, the check is skipped, so
a host with such credentials does not notice an emptied destination; see a host with such credentials does not notice an emptied destination; see
[docs/REPOSTRUCTURE.md](docs/REPOSTRUCTURE.md#marker-file-vaultik-destinationtxt). [docs/REPOSTRUCTURE.md](REPOSTRUCTURE.md#marker-file-vaultik-destinationtxt).
The `file://` backend never creates its destination directory, so a write to a The `file://` backend never creates its destination directory, so a write to a
missing one fails. missing one fails.
The `{remote-key}` directory name is a one-way double SHA-256 hash of the human The `{remote-key}` directory name is a one-way double SHA-256 hash of the human
snapshot ID, so the human ID (hostname, snapshot name, timestamp) is never snapshot ID, so the human ID (hostname, snapshot name, timestamp) is never
written to the store as a directory name. See written to the store as a directory name. See
[docs/REPOSTRUCTURE.md](docs/REPOSTRUCTURE.md#remote-key-derivation) for the [docs/REPOSTRUCTURE.md](REPOSTRUCTURE.md#remote-key-derivation) for the
derivation and a worked example. derivation and a worked example.
## Thread Safety ## Thread Safety
+1 -1
View File
@@ -304,7 +304,7 @@ so an operator can weigh them rather than discover them.
4. **A snapshot is marked complete in the local DB only after its metadata is 4. **A snapshot is marked complete in the local DB only after its metadata is
uploaded** - `finalizeSnapshotMetadata` runs `ExportSnapshotMetadata` first uploaded** - `finalizeSnapshotMetadata` runs `ExportSnapshotMetadata` first
and records completion (`MarkSnapshotComplete`) only once the export succeeds and records completion (`MarkSnapshotComplete`) only once the export succeeds
(see the backup data flow in [ARCHITECTURE.md](../ARCHITECTURE.md)). A crash (see the backup data flow in [ARCHITECTURE.md](ARCHITECTURE.md)). A crash
during the export therefore leaves the snapshot incomplete, so the next during the export therefore leaves the snapshot incomplete, so the next
backup's `PruneDatabase` drops it and re-backs-up its data, rather than backup's `PruneDatabase` drops it and re-backs-up its data, rather than
leaving a completed-looking row in the local index with no matching metadata leaving a completed-looking row in the local index with no matching metadata
+6 -1
View File
@@ -23,6 +23,11 @@ runs the release build in `.gitea/workflows/release.yml`.
# Completed Steps # Completed Steps
- 2026-11-10: `script/fmt` and `script/fmt-check` now format and check all
Markdown with `prettier`
([issue #411](https://git.eeqj.de/sneak/vaultik/issues/411)). The architecture
document and this file moved to `docs/`, and the example config to `configs/`.
- 2026-11-10: Printed the status and progress lines of `remote info` and - 2026-11-10: Printed the status and progress lines of `remote info` and
`snapshot verify` through `internal/ui`, with its marker and color, as the `snapshot verify` through `internal/ui`, with its marker and color, as the
README describes ([issue #410](https://git.eeqj.de/sneak/vaultik/issues/410)). README describes ([issue #410](https://git.eeqj.de/sneak/vaultik/issues/410)).
@@ -1216,4 +1221,4 @@ runs the release build in `.gitea/workflows/release.yml`.
# Future Steps # Future Steps
Work planned after 1.0 is listed in the README [roadmap](README.md#roadmap). Work planned after 1.0 is listed in the README [roadmap](../README.md#roadmap).
+1 -1
View File
@@ -56,7 +56,7 @@ var (
errRecipientNotX25519 = errors.New( errRecipientNotX25519 = errors.New(
"not a valid recipient; only X25519 age1... public keys are supported") "not a valid recipient; only X25519 age1... public keys are supported")
errNoSnapshots = errors.New( errNoSnapshots = errors.New(
"at least one snapshot must be configured (see config.example.yml)") "at least one snapshot must be configured (see configs/config.example.yml)")
errSnapshotNoPaths = errors.New("snapshot must have at least one path") errSnapshotNoPaths = errors.New("snapshot must have at least one path")
errChunkSizeTooSmall = errors.New("chunk_size must be at least 1MB") errChunkSizeTooSmall = errors.New("chunk_size must be at least 1MB")
errBlobSizeTooSmall = errors.New( errBlobSizeTooSmall = errors.New(
+4 -4
View File
@@ -90,12 +90,12 @@ func TestConfigLoad(t *testing.T) {
} }
// TestExampleConfigIsScrubbedAndLoads checks that the shipped // TestExampleConfigIsScrubbedAndLoads checks that the shipped
// config.example.yml carries only neutral placeholders (no real credentials, // configs/config.example.yml carries only neutral placeholders (no real
// private addresses, or internal host names) and still parses. // credentials, private addresses, or internal host names) and still parses.
func TestExampleConfigIsScrubbedAndLoads(t *testing.T) { func TestExampleConfigIsScrubbedAndLoads(t *testing.T) {
t.Parallel() t.Parallel()
examplePath := filepath.Join("..", "..", "config.example.yml") examplePath := filepath.Join("..", "..", "configs", "config.example.yml")
cfg, err := Load(examplePath) cfg, err := Load(examplePath)
if err != nil { if err != nil {
@@ -361,7 +361,7 @@ func TestDocumentedSizeDefaults(t *testing.T) {
} }
// TestDocumentedSizeExamples checks the 1MB minimum chunk_size and that // TestDocumentedSizeExamples checks the 1MB minimum chunk_size and that
// every size the README, config.example.yml and the config init template // every size the README, configs/config.example.yml and the config init template
// list as an example is accepted. // list as an example is accepted.
func TestDocumentedSizeExamples(t *testing.T) { func TestDocumentedSizeExamples(t *testing.T) {
t.Parallel() t.Parallel()