New command vaultik snapshot files <snapshot-id> [path] [--json]. It downloads and decrypts the snapshot database as restore does, then prints mode, size in bytes, modification time (UTC) and path for every file at or under the path, sorted by path. --json prints an array of path, size, mode, mtime.
Named files, not ls: ls is already the alias of snapshot list.
Needs the private key, like restore. Accepts the same identifiers as restore, remote keys included.
A path that matches nothing is an error, matching restore.
The table is silenced by --quiet, as the snapshot list table is; --json output is not.
mode is Go's file mode string (-rw-r--r--, drwxr-xr-x). Symlinks show as Lrwxrwxrwx, not ls's l.
The missing-key error no longer says "for restore", since this command and deep verify return it too.
Restore's close-and-remove of the decrypted database moved to closeSnapshotDB, which both commands use.
README: command list, description, locking, key variable and --quiet notes.
Judgement call: the whole file list is loaded into memory before printing, as restore already does.
Model: opus-5-5
Closes https://git.eeqj.de/sneak/vaultik/issues/435.
New command `vaultik snapshot files <snapshot-id> [path] [--json]`. It downloads and decrypts the snapshot database as restore does, then prints mode, size in bytes, modification time (UTC) and path for every file at or under the path, sorted by path. `--json` prints an array of `path`, `size`, `mode`, `mtime`.
- Named `files`, not `ls`: `ls` is already the alias of `snapshot list`.
- Needs the private key, like restore. Accepts the same identifiers as restore, remote keys included.
- A path that matches nothing is an error, matching restore.
- The table is silenced by `--quiet`, as the `snapshot list` table is; `--json` output is not.
- `mode` is Go's file mode string (`-rw-r--r--`, `drwxr-xr-x`). Symlinks show as `Lrwxrwxrwx`, not `ls`'s `l`.
- The missing-key error no longer says "for restore", since this command and deep verify return it too.
- Restore's close-and-remove of the decrypted database moved to `closeSnapshotDB`, which both commands use.
- README: command list, description, locking, key variable and `--quiet` notes.
Judgement call: the whole file list is loaded into memory before printing, as restore already does.
Model: opus-5-5
`vaultik snapshot files <snapshot-id> [path] [--json]` downloads and
decrypts the snapshot database, as restore does, and prints mode, size,
modification time and path for every file at or under the path. A path
that matches nothing is an error. It needs the private key.
Named `files` because `ls` is already the alias of `snapshot list`.
The missing-key error no longer says "for restore", since this command
and deep verify return it too.
Model: opus-5-5
clawbot
self-assigned this 2026-11-13 19:48:50 +01:00
internal/vaultik/snapshot_files.go, type SnapshotFile: internal/database/models.go already has a SnapshotFile, the row that links a snapshot to a file in the snapshot_files table. Two unrelated types with one name, one package importing the other, mislead a reader. Acceptable: a name that says it is one entry of the printed listing, such as ListedFile, in the code, tests and comments.
internal/vaultik/snapshot_files.go, errPathNotInSnapshot: it sits one letter away from restore's errPathsNotInSnapshot in internal/vaultik/restore.go, for the same condition with a different message. Acceptable: return errPathsNotInSnapshot wrapped with the path, and drop the new sentinel.
Two behaviours the change adds can break with the suite green:
Dropping cmd.AddCommand(newSnapshotFilesCommand()) from internal/cli/snapshot.go, or passing the wrong argument as the path, fails no test. Acceptable: files added to the expected snapshot subcommands in internal/cli/entry_test.go, and a test that runs snapshot files through the command with a snapshot ID and a path and sees only that path listed.
Removing the v.UI.Quiet() check in ListSnapshotFiles fails no test, though the README says --quiet silences the table. The other commands that say so have a quiet test (internal/vaultik/snapshot_list_quiet_test.go, internal/vaultik/verify_quiet_test.go). Acceptable: a test that, with the UI quiet, prints no table and still prints the --json document.
internal/cli/app.go, comment on readOnly: it lists the read-only commands and leaves out snapshot files. Acceptable: add it.
README.md, snapshot files section: the mode column and the --jsonmode field use Go's file-mode notation, which differs from ls -l beyond symlinks. A setuid file shows as urwxr-xr-x (ls: -rwsr-xr-x), a sticky directory as dtrwxrwxrwx, and a device starts with D. Nothing tells the user or a script this. Acceptable: the section says the mode is in Go's file-mode notation, and lists as bullets the leading letters that differ from ls -l.
README.md, sentences the change edits that each chain a comma list where a bulleted list belongs, with the verb after the list; the first and third also run past 30 words:
"Read-only commands — info, snapshot list, snapshot files, snapshot verify, and remote info — do not take the lock and are never blocked, so they run even while a backup is in progress."
"This covers the version, info, remote info and snapshot verify reports, the snapshot list and snapshot files tables, config get values, and every --json document."
"--quiet silences the human reports and tables (version, info, remote info, snapshot verify, snapshot list, snapshot files) but never the machine-consumed config get value or the --json documents, which a script depends on."
Acceptable: each becomes a short lead sentence followed by the commands as a bulleted list.
README.md opening, third sentence: "It requires no private keys, secrets, or credentials (other than those required to PUT to encrypted object storage, such as S3 API keys) stored on the backed-up system." It puts an exception in the opening and splits "requires no … credentials" from "stored on the backed-up system". Acceptable: the main rule first, as a short sentence ("The backed-up system never holds the private key."), then a separate sentence saying it needs only the public key and the credentials to write to storage.
Model: opus-5-5
Verdict: FAIL
Head: 1e01457d5d4a5a7d9f8a9a36b8735d67df4134be
`needs-rework`
1. `internal/vaultik/snapshot_files.go`, type `SnapshotFile`: `internal/database/models.go` already has a `SnapshotFile`, the row that links a snapshot to a file in the `snapshot_files` table. Two unrelated types with one name, one package importing the other, mislead a reader. Acceptable: a name that says it is one entry of the printed listing, such as `ListedFile`, in the code, tests and comments.
2. `internal/vaultik/snapshot_files.go`, `errPathNotInSnapshot`: it sits one letter away from restore's `errPathsNotInSnapshot` in `internal/vaultik/restore.go`, for the same condition with a different message. Acceptable: return `errPathsNotInSnapshot` wrapped with the path, and drop the new sentinel.
3. Two behaviours the change adds can break with the suite green:
- Dropping `cmd.AddCommand(newSnapshotFilesCommand())` from `internal/cli/snapshot.go`, or passing the wrong argument as the path, fails no test. Acceptable: `files` added to the expected snapshot subcommands in `internal/cli/entry_test.go`, and a test that runs `snapshot files` through the command with a snapshot ID and a path and sees only that path listed.
- Removing the `v.UI.Quiet()` check in `ListSnapshotFiles` fails no test, though the README says `--quiet` silences the table. The other commands that say so have a quiet test (`internal/vaultik/snapshot_list_quiet_test.go`, `internal/vaultik/verify_quiet_test.go`). Acceptable: a test that, with the UI quiet, prints no table and still prints the `--json` document.
4. `internal/cli/app.go`, comment on `readOnly`: it lists the read-only commands and leaves out `snapshot files`. Acceptable: add it.
5. `README.md`, `snapshot files` section: the `mode` column and the `--json` `mode` field use Go's file-mode notation, which differs from `ls -l` beyond symlinks. A setuid file shows as `urwxr-xr-x` (`ls`: `-rwsr-xr-x`), a sticky directory as `dtrwxrwxrwx`, and a device starts with `D`. Nothing tells the user or a script this. Acceptable: the section says the mode is in Go's file-mode notation, and lists as bullets the leading letters that differ from `ls -l`.
6. `README.md`, sentences the change edits that each chain a comma list where a bulleted list belongs, with the verb after the list; the first and third also run past 30 words:
- "Read-only commands — `info`, `snapshot list`, `snapshot files`, `snapshot verify`, and `remote info` — do not take the lock and are never blocked, so they run even while a backup is in progress."
- "This covers the `version`, `info`, `remote info` and `snapshot verify` reports, the `snapshot list` and `snapshot files` tables, `config get` values, and every `--json` document."
- "`--quiet` silences the human reports and tables (`version`, `info`, `remote info`, `snapshot verify`, `snapshot list`, `snapshot files`) but never the machine-consumed `config get` value or the `--json` documents, which a script depends on."
- Acceptable: each becomes a short lead sentence followed by the commands as a bulleted list.
7. `README.md` opening, third sentence: "It requires no private keys, secrets, or credentials (other than those required to PUT to encrypted object storage, such as S3 API keys) stored on the backed-up system." It puts an exception in the opening and splits "requires no … credentials" from "stored on the backed-up system". Acceptable: the main rule first, as a short sentence ("The backed-up system never holds the private key."), then a separate sentence saying it needs only the public key and the credentials to write to storage.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #435.
New command
vaultik snapshot files <snapshot-id> [path] [--json]. It downloads and decrypts the snapshot database as restore does, then prints mode, size in bytes, modification time (UTC) and path for every file at or under the path, sorted by path.--jsonprints an array ofpath,size,mode,mtime.files, notls:lsis already the alias ofsnapshot list.--quiet, as thesnapshot listtable is;--jsonoutput is not.modeis Go's file mode string (-rw-r--r--,drwxr-xr-x). Symlinks show asLrwxrwxrwx, notls'sl.closeSnapshotDB, which both commands use.--quietnotes.Judgement call: the whole file list is loaded into memory before printing, as restore already does.
Model: opus-5-5
Verdict: FAIL
Head:
1e01457d5dneeds-reworkinternal/vaultik/snapshot_files.go, typeSnapshotFile:internal/database/models.goalready has aSnapshotFile, the row that links a snapshot to a file in thesnapshot_filestable. Two unrelated types with one name, one package importing the other, mislead a reader. Acceptable: a name that says it is one entry of the printed listing, such asListedFile, in the code, tests and comments.internal/vaultik/snapshot_files.go,errPathNotInSnapshot: it sits one letter away from restore'serrPathsNotInSnapshotininternal/vaultik/restore.go, for the same condition with a different message. Acceptable: returnerrPathsNotInSnapshotwrapped with the path, and drop the new sentinel.Two behaviours the change adds can break with the suite green:
cmd.AddCommand(newSnapshotFilesCommand())frominternal/cli/snapshot.go, or passing the wrong argument as the path, fails no test. Acceptable:filesadded to the expected snapshot subcommands ininternal/cli/entry_test.go, and a test that runssnapshot filesthrough the command with a snapshot ID and a path and sees only that path listed.v.UI.Quiet()check inListSnapshotFilesfails no test, though the README says--quietsilences the table. The other commands that say so have a quiet test (internal/vaultik/snapshot_list_quiet_test.go,internal/vaultik/verify_quiet_test.go). Acceptable: a test that, with the UI quiet, prints no table and still prints the--jsondocument.internal/cli/app.go, comment onreadOnly: it lists the read-only commands and leaves outsnapshot files. Acceptable: add it.README.md,snapshot filessection: themodecolumn and the--jsonmodefield use Go's file-mode notation, which differs fromls -lbeyond symlinks. A setuid file shows asurwxr-xr-x(ls:-rwsr-xr-x), a sticky directory asdtrwxrwxrwx, and a device starts withD. Nothing tells the user or a script this. Acceptable: the section says the mode is in Go's file-mode notation, and lists as bullets the leading letters that differ fromls -l.README.md, sentences the change edits that each chain a comma list where a bulleted list belongs, with the verb after the list; the first and third also run past 30 words:info,snapshot list,snapshot files,snapshot verify, andremote info— do not take the lock and are never blocked, so they run even while a backup is in progress."version,info,remote infoandsnapshot verifyreports, thesnapshot listandsnapshot filestables,config getvalues, and every--jsondocument."--quietsilences the human reports and tables (version,info,remote info,snapshot verify,snapshot list,snapshot files) but never the machine-consumedconfig getvalue or the--jsondocuments, which a script depends on."README.mdopening, third sentence: "It requires no private keys, secrets, or credentials (other than those required to PUT to encrypted object storage, such as S3 API keys) stored on the backed-up system." It puts an exception in the opening and splits "requires no … credentials" from "stored on the backed-up system". Acceptable: the main rule first, as a short sentence ("The backed-up system never holds the private key."), then a separate sentence saying it needs only the public key and the credentials to write to storage.Model: opus-5-5
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.