1 Commits
Author SHA1 Message Date
sneak 857feeeddb Record the defect-hunt fixes in TODO.md Completed Steps (closes #334)
check / check (push) Canceled after 0s
Adds a Completed Steps entry, newest first, for every issue from the
defect hunt (#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
#239. Each entry was checked
against the code on `next`. Next Step now says the hunt's fixes have
landed.

Judgement call: #332, closed as
covered by the fix for #296, is
named in that entry rather than given its own.
Judgement call: #351, a Docker
build fix filed while gating these fixes, gets an entry.

Model: opus-5-5
2026-10-14 06:10:15 +00:00
+40 -44
View File
@@ -38,11 +38,10 @@ owner's; a `v*` tag runs the release build in
it skips anything it cannot read it skips anything it cannot read
([issue #310](https://git.eeqj.de/sneak/vaultik/issues/310)). The run ([issue #310](https://git.eeqj.de/sneak/vaultik/issues/310)). The run
printed its skip errors, then `Finished successfully.`, and exited 0, printed its skip errors, then `Finished successfully.`, and exited 0,
so a cron wrapper could not tell it from a complete backup. Such a so a cron wrapper could not tell it from a complete backup. Each
run now keeps its snapshots and then fails with skipped entry, a directory the walk could not list included, is now
`Backup completed, but N file(s) could not be read`, and an entry the counted as failed, and the run keeps its snapshots and then fails with
walk could not read, such as a directory it could not list, now `Backup completed, but N file(s) could not be read`.
counts as failed too.
- 2026-10-14: Kept the local index when `remote nuke` cannot list or - 2026-10-14: Kept the local index when `remote nuke` cannot list or
find the destination store find the destination store
@@ -62,10 +61,10 @@ owner's; a `v*` tag runs the release build in
backup queued every directory and symlink to be backed up, so the backup queued every directory and symlink to be backed up, so the
line ending the walk counted directories and their sizes as files and line ending the walk counted directories and their sizes as files and
data to back up while its enumerated count left them out, and every data to back up while its enumerated count left them out, and every
symlink was reported as backed up on every run. Directories are no symlink was reported as backed up on every run. Directories are now
longer counted as files or data to back up, and a symlink is compared recorded apart and never counted as files or data, and a symlink is
with its record like a regular file, so an unchanged one counts as compared with its record like a regular file, so an unchanged one
unchanged. counts as unchanged.
- 2026-10-14: Refused a backup destination that an unplugged volume - 2026-10-14: Refused a backup destination that an unplugged volume
left empty, as the owner ruled left empty, as the owner ruled
@@ -74,19 +73,18 @@ owner's; a `v*` tag runs the release build in
as an empty store, so `prune` dropped every local snapshot record, and as an empty store, so `prune` dropped every local snapshot record, and
`snapshot create` wrote a whole backup to the internal disk under the `snapshot create` wrote a whole backup to the internal disk under the
empty mount point. Every backup now writes `vaultik-destination.txt` empty mount point. Every backup now writes `vaultik-destination.txt`
at the destination root, and while the local index holds snapshots at the destination root, and while the local index holds snapshots, a
stored there, a destination without it is treated as not present: destination without it is treated as not present: `snapshot create`
`snapshot create` refuses before writing, and `prune` deletes refuses before writing, and `prune` deletes nothing. The `file://`
nothing. The `file://` backend also never creates its destination backend also never creates its destination directory.
directory.
- 2026-10-14: Warned about restored ownership only when an entry's - 2026-10-14: Warned about restored ownership only when an entry's
owner or group differs owner or group differs
([issue #316](https://git.eeqj.de/sneak/vaultik/issues/316)). A ([issue #316](https://git.eeqj.de/sneak/vaultik/issues/316)). Every
restore by a normal user warned that file ownership was not preserved restore by a normal user warned that file ownership was not preserved,
even when every entry came out with its recorded owner and group. The even when every entry came out with its recorded owner and group. The
owner and group the restored entries have on disk are now compared owner and group each restored entry has on disk are now compared with
with the recorded ones, and the warning is printed once if any differ. the recorded ones, and the warning is printed once if any differ.
- 2026-10-14: Made `snapshot list` report a changed destination instead - 2026-10-14: Made `snapshot list` report a changed destination instead
of advising `prune` of advising `prune`
@@ -110,9 +108,9 @@ owner's; a `v*` tag runs the release build in
- 2026-10-14: Named each prefix once in restore, verify and purge errors - 2026-10-14: Named each prefix once in restore, verify and purge errors
([issue #327](https://git.eeqj.de/sneak/vaultik/issues/327)). A ([issue #327](https://git.eeqj.de/sneak/vaultik/issues/327)). A
missing blob during restore, a failed shallow verify and an invalid missing blob during restore, a failed shallow verify and an invalid
purge duration each printed their prefix twice, and a deep verify log purge duration each printed their prefix twice, and deep verify named
line named S3 whatever the destination. Each prefix now appears once, S3 whatever the destination. Each prefix now appears once, and deep
and that log line names storage instead. verify no longer names S3.
- 2026-10-14: Refused credentials in a storage URL's endpoint or rclone - 2026-10-14: Refused credentials in a storage URL's endpoint or rclone
remote name remote name
@@ -120,8 +118,7 @@ owner's; a `v*` tag runs the release build in
inside the `endpoint=` value of an `s3://` URL, and rclone inside the `endpoint=` value of an `s3://` URL, and rclone
`remote,param=value` parameters, were accepted and then printed by `remote,param=value` parameters, were accepted and then printed by
`info`, `remote info` and `snapshot create`. Both are now refused `info`, `remote info` and `snapshot create`. Both are now refused
without echoing the value, as is an `s3://` or `rclone://` query that without echoing the value, as is a query that cannot be decoded.
cannot be decoded.
- 2026-10-14: Ran `$EDITOR` through the shell in `config edit` - 2026-10-14: Ran `$EDITOR` through the shell in `config edit`
([issue #315](https://git.eeqj.de/sneak/vaultik/issues/315)). The ([issue #315](https://git.eeqj.de/sneak/vaultik/issues/315)). The
@@ -143,8 +140,8 @@ owner's; a `v*` tag runs the release build in
each backup as totals each backup as totals
([issue #306](https://git.eeqj.de/sneak/vaultik/issues/306)). Each ([issue #306](https://git.eeqj.de/sneak/vaultik/issues/306)). Each
removed count was followed by `(N remain)`, which read as incomplete removed count was followed by `(N remain)`, which read as incomplete
or orphaned rows left over but counted every snapshot, file, chunk or or orphaned rows left over but was every snapshot, file, chunk or blob
blob left in the local index, so removing the only incomplete snapshot left in the local index, so removing the only incomplete snapshot
printed `1 removed (1 remain)`. Each line now names that figure as the printed `1 removed (1 remain)`. Each line now names that figure as the
total left in the local index. total left in the local index.
@@ -152,9 +149,9 @@ owner's; a `v*` tag runs the release build in
it ([issue #324](https://git.eeqj.de/sneak/vaultik/issues/324)). A it ([issue #324](https://git.eeqj.de/sneak/vaultik/issues/324)). A
blob was freed only once every file in the snapshot that uses it had blob was freed only once every file in the snapshot that uses it had
been restored, which a file outside the selected paths, or one that been restored, which a file outside the selected paths, or one that
failed under `--skip-errors`, never is, so such a restore kept those failed under `--skip-errors`, never is, so such a restore kept that
blobs in the temporary cache until it ended. A cached blob is now file's blobs in the temporary cache until it ended. A cached blob is
freed once no file still pending in this restore uses it. now freed as soon as no file still pending in this restore uses it.
- 2026-10-13: Kept the whole startup error when it contains `): ` - 2026-10-13: Kept the whole startup error when it contains `): `
([issue #320](https://git.eeqj.de/sneak/vaultik/issues/320)). A ([issue #320](https://git.eeqj.de/sneak/vaultik/issues/320)). A
@@ -237,18 +234,17 @@ owner's; a `v*` tag runs the release build in
directory directory
([issue #296](https://git.eeqj.de/sneak/vaultik/issues/296)). The ([issue #296](https://git.eeqj.de/sneak/vaultik/issues/296)). The
listing did not follow a symlinked `metadata/` or `blobs/`, while listing did not follow a symlinked `metadata/` or `blobs/`, while
reads and writes did, so what was behind the link listed as empty; reads and writes did, so the store listed as empty and `prune` dropped
with `metadata/` linked, `prune` then dropped the local snapshot the local snapshot records and deleted every blob. The listings now
records and deleted every blob. The listings now read through such a read through such a link, and fail when its target is missing
link, and fail when its target is missing
([issue #332](https://git.eeqj.de/sneak/vaultik/issues/332)). ([issue #332](https://git.eeqj.de/sneak/vaultik/issues/332)).
- 2026-10-13: Made `snapshot verify --deep --json` report its blob - 2026-10-13: Made `snapshot verify --deep --json` report its blob
counts ([issue #314](https://git.eeqj.de/sneak/vaultik/issues/314)). counts ([issue #314](https://git.eeqj.de/sneak/vaultik/issues/314)).
Deep verify set `verified` only on success and never set `missing`, Deep verify set `verified` only on success and never set `missing`,
so a failed run reported 0 for both. It now counts each blob whose so a failed run reported 0 for both. It now counts each blob whose
contents pass, and before reading any, counts missing and wrong-size contents pass, and first checks every blob's presence and size,
blobs as shallow verify does. counting missing and wrong-size blobs as shallow verify does.
- 2026-10-13: Limited and retried the module download in the Docker - 2026-10-13: Limited and retried the module download in the Docker
build ([issue #351](https://git.eeqj.de/sneak/vaultik/issues/351)). build ([issue #351](https://git.eeqj.de/sneak/vaultik/issues/351)).
@@ -280,7 +276,7 @@ owner's; a `v*` tag runs the release build in
- 2026-10-13: Recorded the stored size of a blob a backup finds already - 2026-10-13: Recorded the stored size of a blob a backup finds already
stored ([issue #300](https://git.eeqj.de/sneak/vaultik/issues/300)). stored ([issue #300](https://git.eeqj.de/sneak/vaultik/issues/300)).
The upload was skipped, but the local index and the manifest kept the The upload was skipped, but the local index and the manifest kept the
size of the local copy, which can differ from the stored object when size of the local copy, which differs from the stored object once
`compression_level` or the recipients changed, so `snapshot verify` `compression_level` or the recipients changed, so `snapshot verify`
failed on a good snapshot. The size the destination store reports for failed on a good snapshot. The size the destination store reports for
the existing object is now recorded. the existing object is now recorded.
@@ -289,7 +285,7 @@ owner's; a `v*` tag runs the release build in
the process on a rollback after Ctrl-C, a failed close of query the process on a rollback after Ctrl-C, a failed close of query
results, or a failed temp file cleanup results, or a failed temp file cleanup
([issue #345](https://git.eeqj.de/sneak/vaultik/issues/345)). Each ([issue #345](https://git.eeqj.de/sneak/vaultik/issues/345)). Each
ended the process at once and skipped the run's cleanup. exited at once with a fatal log line and skipped the run's cleanup.
Read-only transactions now handle the rollback as other transactions Read-only transactions now handle the rollback as other transactions
do, the query functions report a close failure through the error they do, the query functions report a close failure through the error they
already return, and a failed close or removal of a blob temp file already return, and a failed close or removal of a blob temp file
@@ -317,8 +313,7 @@ owner's; a `v*` tag runs the release build in
listing page marked truncated but carrying no continuation token listing page marked truncated but carrying no continuation token
ended the listing without an error, so `prune` saw only the snapshots ended the listing without an error, so `prune` saw only the snapshots
on the first page and treated the blobs of the rest as unreferenced. on the first page and treated the blobs of the rest as unreferenced.
Such a page now fails the listing, so `prune` stops before deleting Such a page now fails the listing, and `prune` deletes nothing.
any blob.
- 2026-10-13: Made shallow `snapshot verify` report a blob it could not - 2026-10-13: Made shallow `snapshot verify` report a blob it could not
check apart from a missing one check apart from a missing one
@@ -334,7 +329,8 @@ owner's; a `v*` tag runs the release build in
([issue #326](https://git.eeqj.de/sneak/vaultik/issues/326)). Restore ([issue #326](https://git.eeqj.de/sneak/vaultik/issues/326)). Restore
planning stopped at the first such file, before the flag could skip planning stopped at the first such file, before the flag could skip
it, so nothing was restored. That file now fails like any other file it, so nothing was restored. That file now fails like any other file
that cannot be restored: skipped under the flag, and fatal without it. that cannot be restored, skipped under the flag while every other
file is restored, and fatal without it.
- 2026-10-13: Recorded each snapshot's new chunk size when its backup - 2026-10-13: Recorded each snapshot's new chunk size when its backup
runs ([issue #311](https://git.eeqj.de/sneak/vaultik/issues/311)). runs ([issue #311](https://git.eeqj.de/sneak/vaultik/issues/311)).
@@ -358,10 +354,10 @@ owner's; a `v*` tag runs the release build in
- 2026-10-13: Printed `snapshot list` and `snapshot purge` sizes like - 2026-10-13: Printed `snapshot list` and `snapshot purge` sizes like
every other command every other command
([issue #312](https://git.eeqj.de/sneak/vaultik/issues/312)). They, ([issue #312](https://git.eeqj.de/sneak/vaultik/issues/312)). They,
and the `bytes` value in terminal log lines, divided by 1024 but and the byte values in terminal log lines, divided by 1024 but
labelled the result KB or MB, so 6,329,198 bytes read 6.0 MB there and labelled the result KB or MB, so 6,329,198 bytes read 6.0 MB there and
6.3 MB in other commands. All three now use 1000-based units, as other 6.3 MB everywhere else. All three now use the 1000-based units of the
commands do. rest of the program.
- 2026-10-13: Stopped a stalled blob read when restore or deep verify - 2026-10-13: Stopped a stalled blob read when restore or deep verify
is interrupted is interrupted
@@ -371,8 +367,8 @@ owner's; a `v*` tag runs the release build in
device outlasted the 30-second shutdown timeout and the decrypted device outlasted the 30-second shutdown timeout and the decrypted
snapshot database and blob cache were left in the temporary snapshot database and blob cache were left in the temporary
directory. Each blob's storage reader is now closed as soon as the directory. Each blob's storage reader is now closed as soon as the
command is cancelled, which ends a stalled read unless it is stuck in command is cancelled, which ends the stalled read and lets the
the kernel. cleanup run.
- 2026-10-13: Made a mistyped subcommand under a group command an error - 2026-10-13: Made a mistyped subcommand under a group command an error
([issue #319](https://git.eeqj.de/sneak/vaultik/issues/319)). ([issue #319](https://git.eeqj.de/sneak/vaultik/issues/319)).