2025-10-23 - 2026-10-23
Overview
3 Releases published by 1 user
Published
v1.0.0-rc3
Published
v1.0.0-rc2
Published
v1.0.0-rc1
178 Pull requests merged by 1 user
Merged
#396 Do not prune when a backup misses an earlier mount point (closes #395)
Merged
#393 Delete metadata directories a backup left without a manifest (closes #390)
Merged
#394 Do not prune after a backup that found a configured path empty (closes #388)
Merged
#392 Go on with a backup when the destination marker cannot be checked (closes #389)
Merged
#391 Keep unreferenced blobs newer than prune_grace_period
Merged
#386 Record the defect-hunt fixes in TODO.md Completed Steps
Merged
#385 Do not prune after a backup that skipped unreadable files
Merged
#381 Exit non-zero when snapshot create --skip-errors skips anything
Merged
#384 Keep the local index when remote nuke cannot list or find the destination
Merged
#383 Stop counting directories and unchanged symlinks as files to back up
Merged
#349 Refuse a backup destination an unplugged volume left empty
Merged
#378 Warn about restored ownership only when an entry's owner or group differs
Merged
#375 Make snapshot list report a changed destination instead of advising prune
Merged
#342 Count a file as deleted only if the previous snapshot of its name had it
Merged
#377 Name each prefix once in restore, verify and purge errors
Merged
#352 Refuse credentials in a storage URL's endpoint or rclone remote name
Merged
#380 Run $EDITOR through the shell in config edit
Merged
#370 Fail snapshot remove when a destination-only snapshot's metadata cannot be deleted
Merged
#379 Label the index cleanup totals as totals
Merged
#372 Free a cached blob once no file still to restore needs it
Merged
#376 Keep the whole startup error when it contains "): "
Merged
#369 Silence prune and snapshot removal status under --cron and --quiet
Merged
#374 Read the rclone config file named by RCLONE_CONFIG
Merged
#367 Make **/ in an exclude pattern match zero directories
Merged
#373 Make the size defaults and the chunk_size minimum 1000-based
Merged
#371 Keep remote metadata when purge cannot remove a snapshot locally
Merged
#365 Fail restore for a requested path that matches nothing
Merged
#368 Make remote nuke delete every object under metadata/ and blobs/
Merged
#357 Make config set create a list for an index under a missing key
Merged
#331 List a file:// destination through a symlinked directory
Merged
#362 Report blob counts from snapshot verify --deep --json
Merged
#354 Limit and retry the module download in the Docker build
Merged
#366 Record each snapshot's uncompressed size when its backup runs
Merged
#353 Stop restore --verify re-reporting files that failed to restore
Merged
#341 Record the stored size of a blob a backup finds already stored
Merged
#364 Return errors instead of exiting on rollback, rows close and blob temp file cleanup
Merged
#363 Stop a stalled snapshot database read when restore or deep verify is interrupted
Merged
#336 Make prune and remote nuke fail when a delete fails
Merged
#333 Make an S3 listing the server cuts short an error
Merged
#348 Report blobs shallow verify could not check apart from missing ones
Merged
#361 Restore the other files when a chunk is in no blob under --skip-errors
Merged
#359 Record each snapshot's new chunk size when its backup runs
Merged
#343 Exit as interrupted when Ctrl-C lands during a local index write
Merged
#358 Print snapshot list and purge sizes like every other command
Merged
#355 Stop a stalled blob read when restore or deep verify is interrupted
Merged
#350 Make a mistyped subcommand under a group command an error
Merged
#335 Make a leading **/ in an exclude pattern match at the top level
Merged
#330 Refuse a relative file:// storage_url and decode its escapes
Merged
#347 Remove the blob temp file when a backup stops part-way
Merged
#346 Check --keep-newer-than before the backup starts
Merged
#344 Stop remote info counting a non-blob file under blobs/
Merged
#339 Make snapshot remove fail for an unknown snapshot ID
Merged
#329 Bind the local index to the s3.* destination too
Merged
#328 Reject a retention duration longer than about 292 years
Merged
#287 Stop a cancelled backup at once under --skip-errors
Merged
#283 Make remote nuke delete leftover .partial uploads
Merged
#285 Never skip a local index error for a directory or symlink
Merged
#282 Count a file a backup could not store as failed
Merged
#279 Report unknown blob figures for a snapshot whose manifest cannot be read
Merged
#278 Keep the progress line of a multi-path snapshot within 100%
Merged
#276 Document that --json skips the confirmation prompt of snapshot remove and prune
Merged
#277 Give a second snapshot create in the same second its own ID
Merged
#275 Stop a backup on a symlink whose target cannot be read
Merged
#274 Write rclone uploads under a temporary name and move them into place
Merged
#273 Exit 130 and say so when a command is interrupted
Merged
#264 Correct doc and help sentences that are false about the code
Merged
#265 Speed up the vaultik and database package tests
Merged
#263 Fix two misleading messages: the readable-config warning and the purge listing error
Merged
#262 Pass s3.part_size to the multipart uploader
Merged
#261 Read the snapshot name using the stored hostname
Merged
#259 Leave remote info orphan figures unknown when a manifest is unreadable
Merged
#260 Quote a string setting that YAML would read as a number
Merged
#257 Store and compare file mtimes to the nanosecond
Merged
#258 Make the process-wide lock atomic with flock
Merged
#256 Write only the document to stdout from snapshot remove --json
Merged
#254 Count each file, byte and upload once in backup statistics
Merged
#252 Keep command output to the README's stdout and stderr rules
Merged
#255 Start the progress reporter once per snapshot, not once per path
Merged
#250 List the files under a path by path, not by string prefix
Merged
#249 Return an error, not a panic, on a malformed snapshot database
Merged
#248 Join the S3 prefix to every key with one slash
Merged
#245 Apply restored owners, modes and times in an order that keeps them
Merged
#247 Mark github.com/spf13/pflag as a direct dependency in go.mod
Merged
#244 Load a config that has no age recipient
Merged
#243 Skip files of an unreadable blob under restore --skip-errors
Merged
#236 Re-vendor the canonical files from sneak/prompts at dd4027b
Merged
#242 Run the local index in WAL mode with a busy timeout
Merged
#241 Record the real uid and gid of backed-up files
Merged
#238 List a missing file:// destination directory as an error
Merged
#237 Reject a retention duration with characters outside its number-and-unit parts
Merged
#234 Re-chunk a known file whose chunks no uploaded blob holds
Merged
#212 Stamp the tag or short commit in a plain docker build (closes #211)
Merged
#209 List only after-1.0 work in the README roadmap
Merged
#210 Run the disk-full restore test again
Merged
#205 Document that migrations are supported and none are added before 1.0 (closes #68)
Merged
#114 next: integrate accumulated work into main
Merged
#202 Vendor the canonical .golangci.yml (gomodguard_v2)
Merged
#201 Route direct-stdout command output through internal/ui (closes #149)
Merged
#200 Mark a snapshot complete only after its metadata export succeeds
Merged
#199 Correct the security claims in docs and comments, and record the accepted risks
Merged
#198 Reject a metadata database truncated to the age header and nonce
Merged
#197 Bound download expansion and escape control chars on the terminal (closes #164)
Merged
#195 Validate blob hashes, offsets and lengths read from the destination
Merged
#196 Parse the age identity key once and accept every identity in it
Merged
#194 Reject a decrypted snapshot database that is not the requested one
Merged
#193 Check blob sizes and the database in shallow verify
Merged
#192 Add negative and boundary tests for blobgen and types (closes #170)
Merged
#189 Wait for the interrupted operation to clean up before exit
Merged
#191 Remove the unused crypto path and write the blob-ID hash step once
Merged
#190 Scrub example config of real credentials and internal hosts
Merged
#188 Give the local index and its export copy an explicit 0600 mode
Merged
#187 Parse age_recipients at config load and never echo the entry
Merged
#186 Open the downloaded snapshot database read-only, on a private temp dir
Merged
#185 Abort the run when packing fails, even under --skip-errors
Merged
#184 Stop config set echoing secrets; reject credential-bearing storage URLs
Merged
#183 Reconcile purge against remote by hashed key, not human ID
Merged
#182 Restore files at 0600 and make the blob hash check unskippable (closes #163)
Merged
#181 Reject a blob_size_limit below the largest possible chunk (closes #167)
Merged
#180 Fail closed on unreadable manifests instead of losing blobs
Merged
#178 Default a scheme-less s3.* endpoint to TLS
Merged
#179 Scope the PID lock to mutating commands
Merged
#176 Keep restore writes inside the target directory
Merged
#175 Trust only uploaded blobs for deduplication (closes #148)
Merged
#173 Add fault-injection tests for interruption and corruption (closes #72)
Merged
#145 Quiet only the stdout UI under --json, not the log level (closes #112)
Merged
#174 Reconcile docs with code across the accuracy-sweep items (closes #74)
Merged
#147 Accept a remote key for restore and verify, and document it (closes #124)
Merged
#144 Add tests for internal/storage URL parsing and the file backend (closes #66)
Merged
#141 Stamp Docker image version from the host; flush profiles on error exit (closes #75)
Merged
#146 Reconcile the schema/migration docs with the code (closes #68)
Merged
#139 Report a prune count that could not be read as unknown, not 0 (closes #96)
Merged
#143 Write file:// blobs atomically via temp file and rename (closes #130)
Merged
#142 Map s3 not-found to storage.ErrNotFound in Get and Stat (closes #129)
Merged
#140 Use one duration parser and fix the --older-than months example (closes #123)
Merged
#135 Drop the lint-guard shell scanner, keep the Dockerfile.lint checks (closes #121)
Merged
#138 Hash the plaintext, not the encrypted bytes, in verify --deep (closes #131)
Merged
#132 Hash-verify the Go toolchain in the release workflow (closes #105)
Merged
#136 VACUUM snapshot metadata through the sqlite driver, not a CLI (closes #120)
Merged
#134 Delete dead code and stale fixtures, fix config set reindent
Merged
#128 Correct remote layout and privacy docs for hashed snapshot keys (closes #67)
Merged
#127 Trigger CI on next, not only main
Merged
#126 Correct --cron flag help to name warnings as unsuppressed (closes #87)
Merged
#111 Gate prune's local-cleanup prose on --json, and give make build a rule
Merged
#109 Suppress the startup banner under --json (closes #106)
Merged
#107 Send diagnostics to stderr and stop dropping log attributes (closes #82, closes #97)
Merged
#104 Make the tagged-release path work on Gitea (closes #65)
Merged
#102 Isolate the lint cache per worktree and context-gate the native lint path
Merged
#98 Make the test gate unfakeable and stop test-integration lying (closes #93)
Merged
#95 Record the stale-branch triage and advance TODO.md (closes #71)
Merged
#92 Make a missing CHECK_EPOCH fail the build instead of faking it (closes #91)
Merged
#89 Make script/cibuild unable to report an unearned green (closes #85)
Merged
#86 Correct the Vaultik.UI doc comment about --cron (closes #84)
Merged
#83 List remote snapshots without requiring the private key (closes #64)
Merged
#79 Run the linter at the pinned version locally too (closes #78)
Merged
#77 Finish the lint remediation: script/cibuild exits 0 (closes #61)
Merged
#62 Update golangci-lint to v2.12.2 with canonical config
Merged
#60 Add .editorconfig (refs #59)
Merged
#58 Move schema_migrations table creation into 000.sql with INTEGER version column
Merged
#51 feat: per-name purge filtering for snapshot purge
Merged
#50 feat: concurrent manifest downloads in ListSnapshots
Merged
#45 fix: replace O(n²) duplicate detection with map-based O(1) lookups
Merged
#55 Remove all ctime usage and storage
Merged
#46 schema: add ON DELETE CASCADE to snapshot_files.file_id and snapshot_blobs.blob_id FKs
Merged
#44 fix: add ON DELETE CASCADE to uploads FK on snapshot_id
Merged
#53 Rename blob_fetch_stub.go to blob_fetch.go
Merged
#49 fix: remove destructive sync from ListSnapshots
Merged
#41 Refactor: break up oversized methods into smaller descriptive helpers
Merged
#39 fix: verify blob hash after download and decryption (closes #5)
Merged
#42 Add make check target and CI workflow
Merged
#23 feat: add progress bar to restore operation
Merged
#37 feat: implement --prune flag on snapshot create (closes #4)
Merged
#22 fix: track and report file restore failures
Merged
#30 Return errors from deleteSnapshotFromLocalDB instead of swallowing them (closes #25)
Merged
#34 Disk-based blob cache with LRU eviction during restore (closes #29)
Merged
#36 Add CompressStream double-close regression test (closes #35)
Merged
#31 Use v.Stdout/v.Stdin instead of os.Stdout for all user-facing output (closes #26)
Merged
#32 Validate table name against allowlist in getTableCount (closes #27)
Merged
#33 Prevent double-close of blobgen.Writer in CompressStream (closes #28)
1 Pull request proposed by 1 user
Proposed
#203 next: integrate accumulated work into main
211 Issues closed from 2 users
Closed
#395 A backup while a volume mounted below a configured path is not mounted deletes the older snapshots holding its files under --prune
Closed
#390 prune never removes the encrypted database a backup left on the destination when its manifest upload failed
Closed
#388 A backup of a source directory left empty by an unmounted volume deletes every older snapshot under --prune
Closed
#389 The documented PUT-only source host fails every backup after its first: the destination marker check needs HEAD permission on S3
Closed
#387 A prune on one host deletes blobs of another host's backup in progress; that backup reports success and cannot be restored
Closed
#334 Record the defect-hunt fixes in TODO.md Completed Steps
Closed
#382 snapshot create --skip-errors --prune deletes the previous snapshot, the only one holding the skipped files
Closed
#310 snapshot create --skip-errors exits 0 and prints "Finished successfully." after skipping files
Closed
#292 remote nuke against a destination it cannot list deletes the local index first
Closed
#305 Directories and symlinks are counted as files to back up on every run, so an unchanged tree reports data backed up
Closed
#239 How should vaultik tell an unplugged file:// volume from a new, empty destination?
Closed
#316 Every restore by a non-root user warns that ownership was not preserved, even when it was
Closed
#317 After storage_url changes, snapshot list advises prune, which then refuses
Closed
#304 The "deleted" figure of a backup counts files that were not deleted since the previous snapshot of that name
Closed
#327 Restore and verify error lines repeat a prefix, and deep verify names S3 for any destination
Closed
#322 Credentials can still be put in storage_url, inside the endpoint or an rclone remote's parameters, and are then printed
Closed
#315 config edit fails when $EDITOR carries arguments
Closed
#340 snapshot remove exits 0 when deleting a destination-only snapshot's metadata fails, and its README promise of a prune command is false on several paths
Closed
#306 The index cleanup before each backup reports total rows as "remain"
Closed
#324 A restore of selected paths keeps decrypted blobs in the temporary cache until it ends
Closed
#320 A config error that contains "): " loses its start, including which setting is wrong
Closed
#294 --cron and --quiet do not silence the status lines of prune
Closed
#321 RCLONE_CONFIG is ignored, so an rclone destination configured there is not found
Closed
#338 Exclude patterns /**/x and a/**/b do not match as in gitignore
Closed
#313 Byte-size settings: the defaults and the chunk-size minimum are 1024-based while the docs, the parser and the messages are 1000-based
Closed
#337 snapshot purge exits 0 and still deletes the remote metadata when it cannot remove a snapshot from the local index
Closed
#309 snapshot restore ignores a requested path that matches nothing, and exits 0
Closed
#291 remote nuke leaves a snapshot database without a manifest, and non-blob files under blobs/, and says the store is empty
Closed
#308 config set with a list index on a key that does not exist writes a map, and then no command can load the config
Closed
#296 A symlinked metadata/ or blobs/ directory in a file:// destination lists as empty, and prune then deletes every blob
Closed
#314 snapshot verify --deep --json reports "missing": 0 and "verified": 0 when it fails
Closed
#351 The Docker build hangs for as long as a stalled connection to the Go module proxy lasts
Closed
#360 snapshot list's UNCOMPRESSED SIZE of an older snapshot changes after a later backup
Closed
#323 restore --skip-errors --verify reports a file that failed to restore again as a checksum failure
Closed
#300 A reused blob is recorded with the size of a local copy that was never stored, so snapshot verify fails on a good snapshot
Closed
#345 internal/database and the blob upload step still end the process on a rollback after Ctrl-C, a failed close of query results, or a failed temp file cleanup
Closed
#356 Interrupting a stalled read of the snapshot database leaves decrypted data in the temp directory
Closed
#290 prune and remote nuke exit 0 when a delete fails, and nuke still says the store is empty
Closed
#297 An S3 listing the server marks truncated without a continuation token is taken as complete, so prune can delete blobs still in use
Closed
#318 Shallow snapshot verify reports any error reading a blob's size as "Missing", and drops the error
Closed
#326 Under --skip-errors, one file whose chunk is in no blob aborts the whole restore before anything is restored
Closed
#311 snapshot list shows a NEW CHUNK SIZE of 0 B for a snapshot whose change is a modified file
Closed
#301 Ctrl-C during a backup can end with "FATAL: failed to rollback transaction" and exit 1 instead of the interrupted exit
Closed
#312 snapshot list and the snapshot purge listing print 1024-based sizes labelled MB, unlike every other command
Closed
#325 Interrupting a restore during a slow blob read leaves the decrypted snapshot database and decrypted file data in the temp directory
Closed
#319 A mistyped subcommand under snapshot, config, remote, database or completion exits 0 and does nothing
Closed
#303 Exclude patterns starting with **/ miss a match directly under the source path
Closed
#299 A relative file:// path is accepted, so the destination moves with the working directory and a backup can exit 0 and be unrestorable
Closed
#302 A failed or interrupted backup leaves its half-written blob in the temp directory
Closed
#307 An invalid --keep-newer-than is checked only after the backup, which is then reported as failed and retention never runs
Closed
#295 remote info counts a file under blobs/ that is not a blob as an orphaned blob
Closed
#293 snapshot remove reports success for a snapshot that does not exist
Closed
#332 A file:// destination whose metadata/ or blobs/ is a symlink to a missing target lists as empty, so prune deletes every blob
Closed
#298 With the s3.* configuration, a changed bucket or prefix is not detected, and the next backup reports success but cannot be restored
Closed
#289 A retention duration of 293 years or more deletes every snapshot
Closed
#288 Defect hunt on next before the release candidate
Closed
#204 Daemon mode after 1.0: watch for file changes so frequent backups skip the full scan
Closed
#286 An interrupted --skip-errors backup keeps opening every remaining file and logs each one as failed
Closed
#281 remote nuke reports the destination store empty while a leftover .partial upload remains
Closed
#284 Under --skip-errors, a local index error while recording a directory or symlink is skipped instead of stopping the backup
Closed
#280 A file skipped while a backup is processed is reported as "unchanged" and its bytes as "backed up"
Closed
#272 remote info shows 0 blobs and 0 B for a snapshot whose manifest cannot be read
Closed
#271 Progress lines over-report on the second and later paths of a multi-path snapshot
Closed
#268 The help and README do not say that --json skips the confirmation prompt of snapshot remove and prune
Closed
#270 Two snapshot create runs of one name within the same second fail on the snapshot ID
Closed
#269 A symlink whose target cannot be read is left out of the snapshot silently, even without --skip-errors
Closed
#266 A blob upload to an rclone destination cut off by a hard kill leaves a partial object that the next backup trusts
Closed
#267 An interrupted snapshot create, restore or verify exits 0 and prints nothing
Closed
#233 Doc and help sentences that are false about the current tree
Closed
#235 The internal/vaultik and internal/database tests take longer than the 20-second target
Closed
#240 Two misleading messages: a credentials warning for a config with no credentials, and a doubled error prefix
Closed
#232 s3.part_size is documented and accepted but has no effect
Closed
#230 A hostname containing _ makes per-name retention silently do nothing
Closed
#228 remote info counts a live snapshot's blobs as orphaned when a manifest cannot be read, and prints store names unescaped
Closed
#229 config set cannot store a string that looks like a number
Closed
#226 A file rewritten within the same second as its recorded mtime is never backed up again
Closed
#227 The process lock is check-then-write, so two writers started together can both acquire it
Closed
#251 snapshot remove --json prints its remote-cleanup warning on stdout, ahead of the document
Closed
#225 Backup statistics are wrong in the printed summary and in the snapshots table
Closed
#224 Command output breaks the README's stdout and stderr rules in three places
Closed
#253 A backup without --cron panics when a snapshot has more than one path
Closed
#223 Path filters match by case-insensitive string prefix: restoring /home/u/doc also restores doc2, Doc3 and doc.txt.bak
Closed
#231 A malformed snapshot database crashes restore with a Go panic instead of an error
Closed
#222 With an s3://bucket/prefix URL, objects are stored as prefixblobs/... instead of prefix/blobs/...
Closed
#219 Restore applies directory modes and times before writing the contents, and file modes before ownership
Closed
#246 The pre-commit hook fails on every commit: go.mod marks a directly imported module as indirect
Closed
#221 The documented "restoring on another machine" steps fail at the first command
Closed
#218 snapshot restore --skip-errors aborts on a missing or damaged blob instead of skipping the files that need it
Closed
#213 Re-vendor the canonical files from sneak/prompts at dd4027b
Closed
#217 The local index ignores its WAL and busy-timeout settings, so a read-only command can abort a running backup
Closed
#216 File ownership is never recorded, so a restore as root makes every file root:root
Closed
#220 A file:// destination that is missing (an unmounted volume) is treated as present and empty
Closed
#215 A retention duration with unparsed characters is misread: --keep-newer-than 1.0y deletes every snapshot
Closed
#214 A backup reports success but cannot restore a changed file after the snapshot holding its current version is dropped
Closed
#211 docker build . stamps dev, not the git tag or short commit
Closed
#125 Work remaining before vaultik 1.0
Closed
#208 README roadmap and TODO.md still list finished 1.0 work as remaining
Closed
#207 The disk-full restore test is still skipped although the fix it waited for has landed
Closed
#206 Run every build, test and lint step in the Dockerfiles at nice -n 19
Closed
#68 Reconcile the schema/migration story across code and four documents
Closed
#94 Decide whether feature/daemon-mode is 1.0 scope
Closed
#133 CI runner mac-studio fails every job before the first step (docker network pools exhausted, disk full)
Closed
#113 Run all linting in Docker via Dockerfile.lint + script/lint
Closed
#155 Check blob hashes, offsets and lengths read from the destination before using them
Closed
#156 Restore and deep verify must check the decrypted database is the snapshot that was asked for
Closed
#159 Ctrl-C during restore exits before cleanup, leaving decrypted data in the temp directory
Closed
#177 Interrupted metadata export leaves a snapshot silently treated as complete but unrestorable
Closed
#90 golangci-lint deprecation: gomodguard replaced by gomodguard_v2
Closed
#119 Review toward 1.0: identify and file all next steps
Closed
#73 Security review of the crypto and blob-generation seams
Closed
#76 Decide on renaming internal/log, internal/crypto and internal/types (revive var-naming)
Closed
#101 REPO_POLICIES.md mandates a 30s test timeout that is too tight to be safe
Closed
#149 Route direct-stdout command output through internal/ui
Closed
#171 Correct the security claims in the docs and comments, and write down the accepted risks
Closed
#152 A stream cut right after the age header reads as valid and empty, and restore then reports success
Closed
#164 Bound what a downloaded object may expand to, and escape control characters from the destination before printing
Closed
#165 Parse the age private key once, accept every identity in it, and stop showing it typed on the command line
Closed
#169 Shallow snapshot verify ignores object sizes and reports more than it checked
Closed
#170 Negative and boundary tests for internal/blobgen and internal/types (and internal/crypto if it survives)
Closed
#151 Remove the unused second encryption path and unused secret types; write the blob-ID hash step once
Closed
#172 config.example.yml carries a real-looking S3 key pair and internal host names
Closed
#168 Give the local index and its export copy an explicit 0600 mode
Closed
#153 Parse age_recipients when the config loads, and never print the entry in an error
Closed
#162 Open the downloaded snapshot database read-only, keep it in a private temp directory, remove it on every path
Closed
#161 Under --skip-errors a packing failure can record a file that cannot be restored
Closed
#166 config set echoes secrets and keeps a loose file mode; a storage_url carrying credentials is accepted and echoed
Closed
#160 snapshot purge deletes every local snapshot record and then purges nothing
Closed
#163 Restore: create files 0600, remove partial files, and make the blob hash check impossible to skip
Closed
#167 Reject a blob_size_limit below the largest possible chunk
Closed
#157 Prune must delete nothing when a manifest cannot be read, and a manifest must never omit a blob
Closed
#158 s3.use_ssl is documented as defaulting to true but the code defaults to plain HTTP
Closed
#150 Scope the process-wide PID lock to mutating commands
Closed
#154 Restore must keep every write inside the target directory
Closed
#148 Interrupted blob upload leaves committed chunk rows; a retry silently produces an unrestorable snapshot
Closed
#72 Fault-injection tests: prove backups survive interruption and corruption
Closed
#112 Under --json, prune deletes local index rows with no signal in either stream
Closed
#74 Documentation accuracy sweep: undocumented behavior and stale claims
Closed
#137 S3 test credentials for ber1app1 remain in git history after the fixture was deleted
Closed
#124 Document and test restoring on another machine
Closed
#66 Add tests for internal/storage — the backend abstraction has zero coverage
Closed
#75 Docker builds report unknown version, and profiling output is truncated on error
Closed
#96 getTableCount errors are discarded, so a failed query reports as a count of zero
Closed
#130 Interrupted blob upload leaves a partial object the next run trusts as complete (file:// backend)
Closed
#129 S3Storer.Get/Stat return the raw SDK error, not storage.ErrNotFound
Closed
#123 Two duration parsers, and the documented --older-than example deletes almost every snapshot
Closed
#121 Rework the lint-guard shell scanner in cmd/vaultik/lintdocker_test.go (second-review findings on the milestone PR)
Closed
#131 verify --deep hashes encrypted bytes but compares to the plaintext blob ID, so it fails on healthy snapshots
Closed
#105 The Go toolchain in the release workflow is version-pinned but not hash-verified
Closed
#120 snapshot create fails on any host without the sqlite3 CLI: VACUUM shells out instead of using the driver
Closed
#70 Delete dead code and stale fixtures before tagging
Closed
#67 Docs misstate the remote layout and understate the privacy guarantee
Closed
#122 CI never runs on next or on PRs targeting it
Closed
#87 --cron flag help text misstates what it suppresses
Closed
#116 Guard scanner: shellCode silently discards the rest of a file on an unterminated here-document
Closed
#117 Guard scanner: assertLinterIsContainerised accepts a || host-linter fallback
Closed
#118 Dockerfile.lint citation names an lll finding where the PR records revive
Closed
#115 Host-lint guard scanner goes blind on a phantom heredoc and accepts a || host fallback
Closed
#103 Two fail-closed defects in the new lint isolation
Closed
#88 golangci-lint cache is shared across worktrees, so lint results can come from another tree
Closed
#108 pruneLocalSnapshots writes prose to stdout unconditionally, so prune --json | jq still fails after the banner fix
Closed
#110 make build exits 0 without building anything
Closed
#106 Startup banner goes to stdout and --json does not suppress it, so every --json document is preceded by three lines of prose
Closed
#82 Logger writes to stdout, so any warning corrupts --json output
Closed
#97 TTYHandler silently discards log.With attributes, so diagnostics differ between terminal and CI
Closed
#65 Make the tagged-release path actually work on Gitea
Closed
#80 Harden the pinned-linter gate: context-gate the native path, and make bootstrap yield a working machine
Closed
#99 script/lint shares one golangci-lint cache across worktrees, so one tree's findings are served for another
Closed
#69 make test-integration is a silent no-op — no file carries the integration build tag
Closed
#93 script/test omits -count=1, so Go's test cache can satisfy the gate without running tests
Closed
#81 The unencrypted manifest publishes backup timestamps and a per-blob size profile
Closed
#100 golangci-lint warns on every run: gomodguard is deprecated, replaced by gomodguard_v2
Closed
#71 Triage the 15 stale remote branches; two may contain unlanded fixes
Closed
#91 Adopt the remaining upstream CHECK_EPOCH hardening (expanded form, unset guard, unique epoch, script/docker)
Closed
#85 script/cibuild reports a green it did not earn when the tree is unchanged
Closed
#84 Vaultik.UI doc comment misdescribes how --cron suppresses output
Closed
#64 snapshot list must list remote snapshots without requiring the private key
Closed
#78 make lint does not use the pinned linter version, so local green does not mean CI green
Closed
#59 Add .editorconfig and the standard .golangci.yml
Closed
#61 Remediate lint findings surfaced by the standard .golangci.yml
Closed
#57 Move schema_migrations table creation into 000.sql with INTEGER version column
Closed
#3 Daemon mode not implemented
Closed
#9 PurgeSnapshots operates across all snapshot names, no per-name filtering
Closed
#14 Manifest is unencrypted — leaks blob count and sizes
Closed
#17 No database migration support — schema changes require full re-backup
Closed
#43 Add branch protection to main branch
Closed
#8 ListSnapshots downloads manifests synchronously for unknown remote snapshots
Closed
#12 RemoveAllSnapshots has O(n²) duplicate detection for snapshot IDs
Closed
#10 syncWithRemote deletes snapshot records without cleaning up related tables
Closed
#54 Remove all ctime usage and storage
Closed
#19 snapshot_files FK on file_id lacks ON DELETE CASCADE
Closed
#18 uploads table FK on snapshot_id lacks ON DELETE CASCADE
Closed
#13 ctime is in schema and model but verify scanner populates it correctly
Closed
#52 Rename blob_fetch_stub.go to blob_fetch.go
Closed
#15 ListSnapshots has destructive side effect: deletes local snapshots not in remote
Closed
#1 find bugs or incomplete functionality for 1.0
Closed
#40 Refactor: break up oversized methods (>100-150 lines)
Closed
#5 Restore: downloaded blob hash is not verified
Closed
#16 PruneBlobs has O(n²) duplicate snapshot ID detection
Closed
#11 Restore: blobCache grows unboundedly, will OOM with large backups
Closed
#20 Restore has no progress bar for file restoration
Closed
#6 deleteSnapshotFromLocalDB silently ignores all errors
Closed
#4 --prune flag on snapshot create is a TODO
Closed
#21 Restore silently continues when individual file restoration fails
Closed
#25 deleteSnapshotFromLocalDB silently swallows all errors and always returns nil
Closed
#7 getTableCount uses fmt.Sprintf for SQL table name — potential SQL injection
Closed
#35 Add regression test for CompressStream double-close fix (#28)
Closed
#26 Multiple methods write to os.Stdout instead of v.Stdout, breaking testability
Closed
#29 Unbounded blob cache during restore can exhaust memory
Closed
#27 SQL injection risk in getTableCount via fmt.Sprintf table name interpolation
Closed
#28 CompressStream double-closes the blobgen.Writer causing potential errors
Closed
#2 Shallow verify path: deep verification is a TODO stub
212 Issues created by 1 user
Opened
#1 find bugs or incomplete functionality for 1.0
Opened
#2 Shallow verify path: deep verification is a TODO stub
Opened
#3 Daemon mode not implemented
Opened
#4 --prune flag on snapshot create is a TODO
Opened
#5 Restore: downloaded blob hash is not verified
Opened
#6 deleteSnapshotFromLocalDB silently ignores all errors
Opened
#7 getTableCount uses fmt.Sprintf for SQL table name — potential SQL injection
Opened
#8 ListSnapshots downloads manifests synchronously for unknown remote snapshots
Opened
#9 PurgeSnapshots operates across all snapshot names, no per-name filtering
Opened
#10 syncWithRemote deletes snapshot records without cleaning up related tables
Opened
#11 Restore: blobCache grows unboundedly, will OOM with large backups
Opened
#12 RemoveAllSnapshots has O(n²) duplicate detection for snapshot IDs
Opened
#13 ctime is in schema and model but verify scanner populates it correctly
Opened
#14 Manifest is unencrypted — leaks blob count and sizes
Opened
#15 ListSnapshots has destructive side effect: deletes local snapshots not in remote
Opened
#16 PruneBlobs has O(n²) duplicate snapshot ID detection
Opened
#17 No database migration support — schema changes require full re-backup
Opened
#18 uploads table FK on snapshot_id lacks ON DELETE CASCADE
Opened
#19 snapshot_files FK on file_id lacks ON DELETE CASCADE
Opened
#20 Restore has no progress bar for file restoration
Opened
#21 Restore silently continues when individual file restoration fails
Opened
#25 deleteSnapshotFromLocalDB silently swallows all errors and always returns nil
Opened
#26 Multiple methods write to os.Stdout instead of v.Stdout, breaking testability
Opened
#27 SQL injection risk in getTableCount via fmt.Sprintf table name interpolation
Opened
#28 CompressStream double-closes the blobgen.Writer causing potential errors
Opened
#29 Unbounded blob cache during restore can exhaust memory
Opened
#35 Add regression test for CompressStream double-close fix (#28)
Opened
#40 Refactor: break up oversized methods (>100-150 lines)
Opened
#43 Add branch protection to main branch
Opened
#52 Rename blob_fetch_stub.go to blob_fetch.go
Opened
#54 Remove all ctime usage and storage
Opened
#57 Move schema_migrations table creation into 000.sql with INTEGER version column
Opened
#59 Add .editorconfig and the standard .golangci.yml
Opened
#61 Remediate lint findings surfaced by the standard .golangci.yml
Opened
#64 snapshot list must list remote snapshots without requiring the private key
Opened
#65 Make the tagged-release path actually work on Gitea
Opened
#66 Add tests for internal/storage — the backend abstraction has zero coverage
Opened
#67 Docs misstate the remote layout and understate the privacy guarantee
Opened
#68 Reconcile the schema/migration story across code and four documents
Opened
#69 make test-integration is a silent no-op — no file carries the integration build tag
Opened
#70 Delete dead code and stale fixtures before tagging
Opened
#71 Triage the 15 stale remote branches; two may contain unlanded fixes
Opened
#72 Fault-injection tests: prove backups survive interruption and corruption
Opened
#73 Security review of the crypto and blob-generation seams
Opened
#74 Documentation accuracy sweep: undocumented behavior and stale claims
Opened
#75 Docker builds report unknown version, and profiling output is truncated on error
Opened
#76 Decide on renaming internal/log, internal/crypto and internal/types (revive var-naming)
Opened
#78 make lint does not use the pinned linter version, so local green does not mean CI green
Opened
#80 Harden the pinned-linter gate: context-gate the native path, and make bootstrap yield a working machine
Opened
#81 The unencrypted manifest publishes backup timestamps and a per-blob size profile
Opened
#82 Logger writes to stdout, so any warning corrupts --json output
Opened
#84 Vaultik.UI doc comment misdescribes how --cron suppresses output
Opened
#85 script/cibuild reports a green it did not earn when the tree is unchanged
Opened
#87 --cron flag help text misstates what it suppresses
Opened
#88 golangci-lint cache is shared across worktrees, so lint results can come from another tree
Opened
#90 golangci-lint deprecation: gomodguard replaced by gomodguard_v2
Opened
#91 Adopt the remaining upstream CHECK_EPOCH hardening (expanded form, unset guard, unique epoch, script/docker)
Opened
#93 script/test omits -count=1, so Go's test cache can satisfy the gate without running tests
Opened
#94 Decide whether feature/daemon-mode is 1.0 scope
Opened
#96 getTableCount errors are discarded, so a failed query reports as a count of zero
Opened
#97 TTYHandler silently discards log.With attributes, so diagnostics differ between terminal and CI
Opened
#99 script/lint shares one golangci-lint cache across worktrees, so one tree's findings are served for another
Opened
#100 golangci-lint warns on every run: gomodguard is deprecated, replaced by gomodguard_v2
Opened
#101 REPO_POLICIES.md mandates a 30s test timeout that is too tight to be safe
Opened
#103 Two fail-closed defects in the new lint isolation
Opened
#105 The Go toolchain in the release workflow is version-pinned but not hash-verified
Opened
#106 Startup banner goes to stdout and --json does not suppress it, so every --json document is preceded by three lines of prose
Opened
#108 pruneLocalSnapshots writes prose to stdout unconditionally, so prune --json | jq still fails after the banner fix
Opened
#110 make build exits 0 without building anything
Opened
#112 Under --json, prune deletes local index rows with no signal in either stream
Opened
#113 Run all linting in Docker via Dockerfile.lint + script/lint
Opened
#115 Host-lint guard scanner goes blind on a phantom heredoc and accepts a || host fallback
Opened
#116 Guard scanner: shellCode silently discards the rest of a file on an unterminated here-document
Opened
#117 Guard scanner: assertLinterIsContainerised accepts a || host-linter fallback
Opened
#118 Dockerfile.lint citation names an lll finding where the PR records revive
Opened
#119 Review toward 1.0: identify and file all next steps
Opened
#120 snapshot create fails on any host without the sqlite3 CLI: VACUUM shells out instead of using the driver
Opened
#121 Rework the lint-guard shell scanner in cmd/vaultik/lintdocker_test.go (second-review findings on the milestone PR)
Opened
#122 CI never runs on next or on PRs targeting it
Opened
#123 Two duration parsers, and the documented --older-than example deletes almost every snapshot
Opened
#124 Document and test restoring on another machine
Opened
#125 Work remaining before vaultik 1.0
Opened
#129 S3Storer.Get/Stat return the raw SDK error, not storage.ErrNotFound
Opened
#130 Interrupted blob upload leaves a partial object the next run trusts as complete (file:// backend)
Opened
#131 verify --deep hashes encrypted bytes but compares to the plaintext blob ID, so it fails on healthy snapshots
Opened
#133 CI runner mac-studio fails every job before the first step (docker network pools exhausted, disk full)
Opened
#137 S3 test credentials for ber1app1 remain in git history after the fixture was deleted
Opened
#148 Interrupted blob upload leaves committed chunk rows; a retry silently produces an unrestorable snapshot
Opened
#149 Route direct-stdout command output through internal/ui
Opened
#150 Scope the process-wide PID lock to mutating commands
Opened
#151 Remove the unused second encryption path and unused secret types; write the blob-ID hash step once
Opened
#152 A stream cut right after the age header reads as valid and empty, and restore then reports success
Opened
#153 Parse age_recipients when the config loads, and never print the entry in an error
Opened
#154 Restore must keep every write inside the target directory
Opened
#155 Check blob hashes, offsets and lengths read from the destination before using them
Opened
#156 Restore and deep verify must check the decrypted database is the snapshot that was asked for
Opened
#157 Prune must delete nothing when a manifest cannot be read, and a manifest must never omit a blob
Opened
#158 s3.use_ssl is documented as defaulting to true but the code defaults to plain HTTP
Opened
#159 Ctrl-C during restore exits before cleanup, leaving decrypted data in the temp directory
Opened
#160 snapshot purge deletes every local snapshot record and then purges nothing
Opened
#161 Under --skip-errors a packing failure can record a file that cannot be restored
Opened
#162 Open the downloaded snapshot database read-only, keep it in a private temp directory, remove it on every path
Opened
#163 Restore: create files 0600, remove partial files, and make the blob hash check impossible to skip
Opened
#164 Bound what a downloaded object may expand to, and escape control characters from the destination before printing
Opened
#165 Parse the age private key once, accept every identity in it, and stop showing it typed on the command line
Opened
#166 config set echoes secrets and keeps a loose file mode; a storage_url carrying credentials is accepted and echoed
Opened
#167 Reject a blob_size_limit below the largest possible chunk
Opened
#168 Give the local index and its export copy an explicit 0600 mode
Opened
#169 Shallow snapshot verify ignores object sizes and reports more than it checked
Opened
#170 Negative and boundary tests for internal/blobgen and internal/types (and internal/crypto if it survives)
Opened
#171 Correct the security claims in the docs and comments, and write down the accepted risks
Opened
#172 config.example.yml carries a real-looking S3 key pair and internal host names
Opened
#177 Interrupted metadata export leaves a snapshot silently treated as complete but unrestorable
Opened
#204 Daemon mode after 1.0: watch for file changes so frequent backups skip the full scan
Opened
#206 Run every build, test and lint step in the Dockerfiles at nice -n 19
Opened
#207 The disk-full restore test is still skipped although the fix it waited for has landed
Opened
#208 README roadmap and TODO.md still list finished 1.0 work as remaining
Opened
#211 docker build . stamps dev, not the git tag or short commit
Opened
#213 Re-vendor the canonical files from sneak/prompts at dd4027b
Opened
#214 A backup reports success but cannot restore a changed file after the snapshot holding its current version is dropped
Opened
#215 A retention duration with unparsed characters is misread: --keep-newer-than 1.0y deletes every snapshot
Opened
#216 File ownership is never recorded, so a restore as root makes every file root:root
Opened
#217 The local index ignores its WAL and busy-timeout settings, so a read-only command can abort a running backup
Opened
#218 snapshot restore --skip-errors aborts on a missing or damaged blob instead of skipping the files that need it
Opened
#219 Restore applies directory modes and times before writing the contents, and file modes before ownership
Opened
#220 A file:// destination that is missing (an unmounted volume) is treated as present and empty
Opened
#221 The documented "restoring on another machine" steps fail at the first command
Opened
#222 With an s3://bucket/prefix URL, objects are stored as prefixblobs/... instead of prefix/blobs/...
Opened
#223 Path filters match by case-insensitive string prefix: restoring /home/u/doc also restores doc2, Doc3 and doc.txt.bak
Opened
#224 Command output breaks the README's stdout and stderr rules in three places
Opened
#225 Backup statistics are wrong in the printed summary and in the snapshots table
Opened
#226 A file rewritten within the same second as its recorded mtime is never backed up again
Opened
#227 The process lock is check-then-write, so two writers started together can both acquire it
Opened
#228 remote info counts a live snapshot's blobs as orphaned when a manifest cannot be read, and prints store names unescaped
Opened
#229 config set cannot store a string that looks like a number
Opened
#230 A hostname containing _ makes per-name retention silently do nothing
Opened
#231 A malformed snapshot database crashes restore with a Go panic instead of an error
Opened
#232 s3.part_size is documented and accepted but has no effect
Opened
#233 Doc and help sentences that are false about the current tree
Opened
#235 The internal/vaultik and internal/database tests take longer than the 20-second target
Opened
#239 How should vaultik tell an unplugged file:// volume from a new, empty destination?
Opened
#240 Two misleading messages: a credentials warning for a config with no credentials, and a doubled error prefix
Opened
#246 The pre-commit hook fails on every commit: go.mod marks a directly imported module as indirect
Opened
#251 snapshot remove --json prints its remote-cleanup warning on stdout, ahead of the document
Opened
#253 A backup without --cron panics when a snapshot has more than one path
Opened
#266 A blob upload to an rclone destination cut off by a hard kill leaves a partial object that the next backup trusts
Opened
#267 An interrupted snapshot create, restore or verify exits 0 and prints nothing
Opened
#268 The help and README do not say that --json skips the confirmation prompt of snapshot remove and prune
Opened
#269 A symlink whose target cannot be read is left out of the snapshot silently, even without --skip-errors
Opened
#270 Two snapshot create runs of one name within the same second fail on the snapshot ID
Opened
#271 Progress lines over-report on the second and later paths of a multi-path snapshot
Opened
#272 remote info shows 0 blobs and 0 B for a snapshot whose manifest cannot be read
Opened
#280 A file skipped while a backup is processed is reported as "unchanged" and its bytes as "backed up"
Opened
#281 remote nuke reports the destination store empty while a leftover .partial upload remains
Opened
#284 Under --skip-errors, a local index error while recording a directory or symlink is skipped instead of stopping the backup
Opened
#286 An interrupted --skip-errors backup keeps opening every remaining file and logs each one as failed
Opened
#288 Defect hunt on next before the release candidate
Opened
#289 A retention duration of 293 years or more deletes every snapshot
Opened
#290 prune and remote nuke exit 0 when a delete fails, and nuke still says the store is empty
Opened
#291 remote nuke leaves a snapshot database without a manifest, and non-blob files under blobs/, and says the store is empty
Opened
#292 remote nuke against a destination it cannot list deletes the local index first
Opened
#293 snapshot remove reports success for a snapshot that does not exist
Opened
#294 --cron and --quiet do not silence the status lines of prune
Opened
#295 remote info counts a file under blobs/ that is not a blob as an orphaned blob
Opened
#296 A symlinked metadata/ or blobs/ directory in a file:// destination lists as empty, and prune then deletes every blob
Opened
#297 An S3 listing the server marks truncated without a continuation token is taken as complete, so prune can delete blobs still in use
Opened
#298 With the s3.* configuration, a changed bucket or prefix is not detected, and the next backup reports success but cannot be restored
Opened
#299 A relative file:// path is accepted, so the destination moves with the working directory and a backup can exit 0 and be unrestorable
Opened
#300 A reused blob is recorded with the size of a local copy that was never stored, so snapshot verify fails on a good snapshot
Opened
#301 Ctrl-C during a backup can end with "FATAL: failed to rollback transaction" and exit 1 instead of the interrupted exit
Opened
#302 A failed or interrupted backup leaves its half-written blob in the temp directory
Opened
#303 Exclude patterns starting with **/ miss a match directly under the source path
Opened
#304 The "deleted" figure of a backup counts files that were not deleted since the previous snapshot of that name
Opened
#305 Directories and symlinks are counted as files to back up on every run, so an unchanged tree reports data backed up
Opened
#306 The index cleanup before each backup reports total rows as "remain"
Opened
#307 An invalid --keep-newer-than is checked only after the backup, which is then reported as failed and retention never runs
Opened
#308 config set with a list index on a key that does not exist writes a map, and then no command can load the config
Opened
#309 snapshot restore ignores a requested path that matches nothing, and exits 0
Opened
#310 snapshot create --skip-errors exits 0 and prints "Finished successfully." after skipping files
Opened
#311 snapshot list shows a NEW CHUNK SIZE of 0 B for a snapshot whose change is a modified file
Opened
#312 snapshot list and the snapshot purge listing print 1024-based sizes labelled MB, unlike every other command
Opened
#313 Byte-size settings: the defaults and the chunk-size minimum are 1024-based while the docs, the parser and the messages are 1000-based
Opened
#314 snapshot verify --deep --json reports "missing": 0 and "verified": 0 when it fails
Opened
#315 config edit fails when $EDITOR carries arguments
Opened
#316 Every restore by a non-root user warns that ownership was not preserved, even when it was
Opened
#317 After storage_url changes, snapshot list advises prune, which then refuses
Opened
#318 Shallow snapshot verify reports any error reading a blob's size as "Missing", and drops the error
Opened
#319 A mistyped subcommand under snapshot, config, remote, database or completion exits 0 and does nothing
Opened
#320 A config error that contains "): " loses its start, including which setting is wrong
Opened
#321 RCLONE_CONFIG is ignored, so an rclone destination configured there is not found
Opened
#322 Credentials can still be put in storage_url, inside the endpoint or an rclone remote's parameters, and are then printed
Opened
#323 restore --skip-errors --verify reports a file that failed to restore again as a checksum failure
Opened
#324 A restore of selected paths keeps decrypted blobs in the temporary cache until it ends
Opened
#325 Interrupting a restore during a slow blob read leaves the decrypted snapshot database and decrypted file data in the temp directory
Opened
#326 Under --skip-errors, one file whose chunk is in no blob aborts the whole restore before anything is restored
Opened
#327 Restore and verify error lines repeat a prefix, and deep verify names S3 for any destination
Opened
#332 A file:// destination whose metadata/ or blobs/ is a symlink to a missing target lists as empty, so prune deletes every blob
Opened
#334 Record the defect-hunt fixes in TODO.md Completed Steps
Opened
#337 snapshot purge exits 0 and still deletes the remote metadata when it cannot remove a snapshot from the local index
Opened
#338 Exclude patterns /**/x and a/**/b do not match as in gitignore
Opened
#340 snapshot remove exits 0 when deleting a destination-only snapshot's metadata fails, and its README promise of a prune command is false on several paths
Opened
#345 internal/database and the blob upload step still end the process on a rollback after Ctrl-C, a failed close of query results, or a failed temp file cleanup
Opened
#351 The Docker build hangs for as long as a stalled connection to the Go module proxy lasts
Opened
#356 Interrupting a stalled read of the snapshot database leaves decrypted data in the temp directory
Opened
#360 snapshot list's UNCOMPRESSED SIZE of an older snapshot changes after a later backup
Opened
#382 snapshot create --skip-errors --prune deletes the previous snapshot, the only one holding the skipped files
Opened
#387 A prune on one host deletes blobs of another host's backup in progress; that backup reports success and cannot be restored
Opened
#388 A backup of a source directory left empty by an unmounted volume deletes every older snapshot under --prune
Opened
#389 The documented PUT-only source host fails every backup after its first: the destination marker check needs HEAD permission on S3
Opened
#390 prune never removes the encrypted database a backup left on the destination when its manifest upload failed
Opened
#395 A backup while a volume mounted below a configured path is not mounted deletes the older snapshots holding its files under --prune
Opened
#397 Rewrite README.md and the other prose documents sentence by sentence, on Fable