2026-03-24 - 2026-09-24
Overview
63 Pull requests merged by 1 user
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
1 Pull request proposed by 1 user
Proposed
#203 next: integrate accumulated work into main
80 Issues closed from 1 user
Closed
#177 Interrupted metadata export leaves a snapshot silently treated as complete but unrestorable
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
#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
#101 REPO_POLICIES.md mandates a 30s test timeout that is too tight to be safe
Closed
#76 Decide on renaming internal/log, internal/crypto and internal/types (revive var-naming)
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
#68 Reconcile the schema/migration story across code and four documents
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
#118 Dockerfile.lint citation names an lll finding where the PR records revive
Closed
#117 Guard scanner: assertLinterIsContainerised accepts a || host-linter fallback
Closed
#116 Guard scanner: shellCode silently discards the rest of a file on an unterminated here-document
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
#110 make build exits 0 without building anything
Closed
#108 pruneLocalSnapshots writes prose to stdout unconditionally, so prune --json | jq still fails after the banner fix
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
#97 TTYHandler silently discards log.With attributes, so diagnostics differ between terminal and CI
Closed
#82 Logger writes to stdout, so any warning corrupts --json output
Closed
#65 Make the tagged-release path actually work on Gitea
Closed
#99 script/lint shares one golangci-lint cache across worktrees, so one tree's findings are served for another
Closed
#80 Harden the pinned-linter gate: context-gate the native path, and make bootstrap yield a working machine
Closed
#93 script/test omits -count=1, so Go's test cache can satisfy the gate without running tests
Closed
#69 make test-integration is a silent no-op — no file carries the integration build tag
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
82 Issues created by 1 user
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 Decide the 1.0.0 release scope and cut the tag
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
#157 Prune must delete nothing when a manifest cannot be read, and a manifest must never omit a blob
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
#165 Parse the age private key once, accept every identity in it, and stop showing it typed on the command line
Opened
#172 config.example.yml carries a real-looking S3 key pair and internal host names
Opened
#171 Correct the security claims in the docs and comments, and write down the accepted risks
Opened
#170 Negative and boundary tests for internal/blobgen and internal/types (and internal/crypto if it survives)
Opened
#169 Shallow snapshot verify ignores object sizes and reports more than it checked
Opened
#168 Give the local index and its export copy an explicit 0600 mode
Opened
#167 Reject a blob_size_limit below the largest possible chunk
Opened
#166 config set echoes secrets and keeps a loose file mode; a storage_url carrying credentials is accepted and echoed
Opened
#164 Bound what a downloaded object may expand to, and escape control characters from the destination before printing
Opened
#163 Restore: create files 0600, remove partial files, and make the blob hash check impossible to skip
Opened
#162 Open the downloaded snapshot database read-only, keep it in a private temp directory, remove it on every path
Opened
#161 Under --skip-errors a packing failure can record a file that cannot be restored
Opened
#160 snapshot purge deletes every local snapshot record and then purges nothing
Opened
#159 Ctrl-C during restore exits before cleanup, leaving decrypted data in the temp directory
Opened
#158 s3.use_ssl is documented as defaulting to true but the code defaults to plain HTTP
Opened
#177 Interrupted metadata export leaves a snapshot silently treated as complete but unrestorable