From b19bd959c7a25c009c55b2109d978d0a30068a48 Mon Sep 17 00:00:00 2001 From: sneak Date: Wed, 14 Oct 2026 05:43:18 +0000 Subject: [PATCH] Record the defect-hunt fixes in TODO.md Completed Steps (closes #334) Adds a Completed Steps entry, newest first, for every issue from the defect hunt (https://git.eeqj.de/sneak/vaultik/issues/288) that a merged fix closed and that had none: the hunt's own issues, those filed while fixing them, and the owner's ruling on https://git.eeqj.de/sneak/vaultik/issues/239. Each entry says in one or two sentences what was wrong and what changed; the detail is in each fix's commit. Next Step now says the hunt's fixes have landed. Judgement call: https://git.eeqj.de/sneak/vaultik/issues/332, closed as covered by the fix for https://git.eeqj.de/sneak/vaultik/issues/296, is named in that entry rather than given its own. Judgement call: https://git.eeqj.de/sneak/vaultik/issues/351, a Docker build fix filed while gating these fixes, gets an entry. Model: opus-5-5 --- TODO.md | 224 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 220 insertions(+), 4 deletions(-) diff --git a/TODO.md b/TODO.md index 9160574..70ba387 100644 --- a/TODO.md +++ b/TODO.md @@ -15,13 +15,229 @@ pre-1.0 # Next Step The 1.0 work is complete on `next`: the scope settled on -[issue #125](https://git.eeqj.de/sneak/vaultik/issues/125) was the work -already planned for 1.0, and all of it has landed. The mechanism to cut -the tag exists and is exercised; what is left is merging `next` to -`main` and tagging, both the owner's. +[issue #125](https://git.eeqj.de/sneak/vaultik/issues/125) has landed, +and so has every fix from the defect hunt before the release candidate +([issue #288](https://git.eeqj.de/sneak/vaultik/issues/288)). What is +left is merging `next` to `main` and tagging the release, both the +owner's; a `v*` tag runs the release build in +`.gitea/workflows/release.yml`. # Completed Steps +- 2026-10-14: Stopped `snapshot create --prune` pruning after a backup + that skipped files it could not read + ([issue #382](https://git.eeqj.de/sneak/vaultik/issues/382)). Such a + prune could delete the only snapshot still holding those files. + +- 2026-10-14: Made `snapshot create --skip-errors` exit non-zero, + instead of 0, when it skips anything it cannot read + ([issue #310](https://git.eeqj.de/sneak/vaultik/issues/310)). + +- 2026-10-14: Kept the local index when `remote nuke` cannot list or + find the destination store + ([issue #292](https://git.eeqj.de/sneak/vaultik/issues/292)). Nuke + had cleared the local snapshot records anyway; it now fails before + removing anything. + +- 2026-10-14: Stopped counting directories and unchanged symlinks as + files to back up + ([issue #305](https://git.eeqj.de/sneak/vaultik/issues/305)). + +- 2026-10-14: Refused a backup destination that an unplugged volume + left empty, as the owner ruled + ([issue #239](https://git.eeqj.de/sneak/vaultik/issues/239)). Every + backup now writes `vaultik-destination.txt` at the destination root, + and while the local index holds snapshots stored there, a destination + without it is treated as not present. + +- 2026-10-14: Warned about restored ownership only when an entry's + owner or group differs from the recorded one + ([issue #316](https://git.eeqj.de/sneak/vaultik/issues/316)); a + restore by a non-root user had warned even when none did. + +- 2026-10-14: Made `snapshot list` report a changed destination instead + of advising `prune`, which refuses in that case + ([issue #317](https://git.eeqj.de/sneak/vaultik/issues/317)). + +- 2026-10-14: Counted a file as deleted by a backup only if the + previous snapshot of the same name listed it + ([issue #304](https://git.eeqj.de/sneak/vaultik/issues/304)); files + that snapshot did not list had been counted too. + +- 2026-10-14: Named each prefix once in restore, verify and purge + errors, some of which repeated it + ([issue #327](https://git.eeqj.de/sneak/vaultik/issues/327)). A deep + verify log line that named S3 whatever the destination now names + storage. + +- 2026-10-14: Refused credentials in a storage URL's endpoint or rclone + remote name, which were accepted and could then be printed + ([issue #322](https://git.eeqj.de/sneak/vaultik/issues/322)). + +- 2026-10-14: Ran `$EDITOR` through the shell in `config edit`, so a + value with arguments, such as `code --wait`, no longer fails + ([issue #315](https://git.eeqj.de/sneak/vaultik/issues/315)). + +- 2026-10-14: Made `snapshot remove` fail, instead of exiting 0, when + it cannot delete the metadata of a snapshot that is only on the + destination store + ([issue #340](https://git.eeqj.de/sneak/vaultik/issues/340)). The + README and the help now say when it prints the `vaultik prune` + follow-up. + +- 2026-10-14: Labelled the totals in the local index cleanup before + each backup as totals + ([issue #306](https://git.eeqj.de/sneak/vaultik/issues/306)). Each + was shown as `(N remain)`, which read as rows left to clean up. + +- 2026-10-13: Freed a cached blob once no file still to restore needs + it ([issue #324](https://git.eeqj.de/sneak/vaultik/issues/324)); one + also used by a file outside the selected paths had stayed in the + temporary cache until the restore ended. + +- 2026-10-13: Kept the whole startup error when it contains `): ` + ([issue #320](https://git.eeqj.de/sneak/vaultik/issues/320)). Such + an error was cut at its last `): `, so the `blob_size_limit` one lost + the setting's name. + +- 2026-10-13: Silenced the status lines of `prune` and snapshot removal + under `--cron` and `--quiet` + ([issue #294](https://git.eeqj.de/sneak/vaultik/issues/294)). + +- 2026-10-13: Read the rclone config file that `RCLONE_CONFIG` names + ([issue #321](https://git.eeqj.de/sneak/vaultik/issues/321)); a + remote defined only there had been reported as not found. + +- 2026-10-13: Made `/**/` in an exclude pattern match zero directories, + as in gitignore + ([issue #338](https://git.eeqj.de/sneak/vaultik/issues/338)); + `a/**/*.log` had missed `a/x.log`. + +- 2026-10-13: Made the `chunk_size` and `blob_size_limit` defaults and + the `chunk_size` minimum 1000-based, like the size parser and the + docs ([issue #313](https://git.eeqj.de/sneak/vaultik/issues/313)). + +- 2026-10-13: Kept a snapshot's remote metadata when `snapshot purge` + cannot remove it from the local index + ([issue #337](https://git.eeqj.de/sneak/vaultik/issues/337)); the + purge had deleted the metadata anyway and exited 0. + +- 2026-10-13: Made `snapshot restore` fail for a requested path that + matches nothing, which it had ignored + ([issue #309](https://git.eeqj.de/sneak/vaultik/issues/309)). + +- 2026-10-13: Made `remote nuke` delete every object under `metadata/` + and `blobs/` + ([issue #291](https://git.eeqj.de/sneak/vaultik/issues/291)); it had + left some, such as a stray `.DS_Store`, while reporting the store + empty. + +- 2026-10-13: Made `config set` create a list for an index under a + missing key + ([issue #308](https://git.eeqj.de/sneak/vaultik/issues/308)); it had + written a map, after which no command could load the config. + +- 2026-10-13: Listed a `file://` destination through a symlinked + `metadata/` or `blobs/`, which had listed as empty + ([issue #296](https://git.eeqj.de/sneak/vaultik/issues/296)). A link + to a missing target now fails the listing + ([issue #332](https://git.eeqj.de/sneak/vaultik/issues/332)). + +- 2026-10-13: Made `snapshot verify --deep --json` report its blob + counts ([issue #314](https://git.eeqj.de/sneak/vaultik/issues/314)); + a failed run had reported 0 missing and 0 verified. + +- 2026-10-13: Limited and retried the module download in the Docker + build ([issue #351](https://git.eeqj.de/sneak/vaultik/issues/351)), + which had hung for as long as a stalled connection to the module + proxy lasted. + +- 2026-10-13: Recorded each snapshot's uncompressed size when its + backup runs + ([issue #360](https://git.eeqj.de/sneak/vaultik/issues/360)). A later + backup could change an older snapshot's UNCOMPRESSED SIZE in + `snapshot list`. + +- 2026-10-13: Stopped `snapshot restore --skip-errors --verify` + reporting a file that failed to restore again as a checksum failure + ([issue #323](https://git.eeqj.de/sneak/vaultik/issues/323)). + +- 2026-10-13: Recorded the stored size of a blob a backup finds already + stored, not the size of its local copy, which can differ, so + `snapshot verify` could fail on a good snapshot + ([issue #300](https://git.eeqj.de/sneak/vaultik/issues/300)). + +- 2026-10-13: Stopped the local index and the blob upload step ending + the process on a failed close of query results or a failed temp file + cleanup ([issue #345](https://git.eeqj.de/sneak/vaultik/issues/345)); + both are now returned as errors. + +- 2026-10-13: Closed the snapshot database's storage reader too when + restore or deep verify is interrupted + ([issue #356](https://git.eeqj.de/sneak/vaultik/issues/356)). + +- 2026-10-13: Made `prune` and `remote nuke` fail when a delete on the + backup destination store fails + ([issue #290](https://git.eeqj.de/sneak/vaultik/issues/290)). + +- 2026-10-13: Made an S3 listing that the server cuts short an error + ([issue #297](https://git.eeqj.de/sneak/vaultik/issues/297)); `prune` + had taken it as complete and could delete blobs still in use. + +- 2026-10-13: Made shallow `snapshot verify` report a blob it could not + check apart from a missing one + ([issue #318](https://git.eeqj.de/sneak/vaultik/issues/318)); any + error checking a blob had counted as missing, its cause dropped. + +- 2026-10-13: Restored the other files when a file's chunk is in no + blob under `--skip-errors` + ([issue #326](https://git.eeqj.de/sneak/vaultik/issues/326)); that + file had stopped the restore before anything was restored. + +- 2026-10-13: Recorded each snapshot's new chunk size when its backup + runs ([issue #311](https://git.eeqj.de/sneak/vaultik/issues/311)). + `snapshot list` could show a NEW CHUNK SIZE of 0 B for a snapshot + whose change was a modified file. + +- 2026-10-13: Made a backup interrupted during a local index write exit + as interrupted + ([issue #301](https://git.eeqj.de/sneak/vaultik/issues/301)); it could + end with `FATAL: failed to rollback transaction` and exit 1 instead of + 130. + +- 2026-10-13: Printed `snapshot list` and `snapshot purge` sizes like + every other command + ([issue #312](https://git.eeqj.de/sneak/vaultik/issues/312)). They, + and the `bytes` value in terminal log lines, were 1024-based but + labelled KB or MB, and now use 1000-based units. + +- 2026-10-13: Closed each blob's storage reader when restore or deep + verify is interrupted, which ends a stalled read unless it is stuck in + the kernel ([issue #325](https://git.eeqj.de/sneak/vaultik/issues/325)). + +- 2026-10-13: Made a mistyped subcommand under `snapshot`, `config`, + `remote`, `database` or `completion` an error + ([issue #319](https://git.eeqj.de/sneak/vaultik/issues/319)); each had + printed its help and exited 0. + +- 2026-10-13: Made an exclude pattern starting with `**/` match + directly under the snapshot path too, as in gitignore + ([issue #303](https://git.eeqj.de/sneak/vaultik/issues/303)). + +- 2026-10-13: Refused a relative `file://` storage URL and decoded its + percent-escapes + ([issue #299](https://git.eeqj.de/sneak/vaultik/issues/299)); a + relative path had moved with the working directory. + +- 2026-10-13: Removed the blob temp file when a backup stops part-way + ([issue #302](https://git.eeqj.de/sneak/vaultik/issues/302)); the + half-written blob had stayed in `$TMPDIR`. + +- 2026-10-13: Checked `--keep-newer-than` before a backup starts + ([issue #307](https://git.eeqj.de/sneak/vaultik/issues/307)); an + invalid value had been read only by the prune after the backup, so + retention never ran. + - 2026-10-13: Stopped `remote info` counting a file under `blobs/` that is not a blob as an orphaned blob ([issue #295](https://git.eeqj.de/sneak/vaultik/issues/295)). A stray -- 2.54.0