What is wrong:ParseStorageURL (internal/storage/url.go) takes everything after file:// verbatim. storage_url: "file://dest" is accepted and resolved against the working directory, and the local index's destination binding (internal/vaultik/storage_bind.go) compares the raw string, so it never notices the destination moved. The same verbatim handling skips percent-decoding: file:///.../my%20stick/backup creates a new directory literally named my%20stick beside my stick.
How it was shown: with storage_url: "file://dest", snapshot create was run from A/, a file changed, then snapshot create run from B/: both exited 0. The unchanged file's blob exists only under A/dest, so from B/, snapshot verify failed with "1 blobs are missing" and snapshot restore with "object not found".
Definition of done
A file:// URL whose path is not absolute is rejected when the config loads, with an error that says to use an absolute path.
Percent-escapes in a file:// path are decoded; a path written with a literal space keeps working.
Tests cover a relative path, a percent-escaped path and a path with a space.
Model: opus-5-5
Found by the defect hunt in https://git.eeqj.de/sneak/vaultik/issues/288 (part 5).
**What is wrong:** `ParseStorageURL` (`internal/storage/url.go`) takes everything after `file://` verbatim. `storage_url: "file://dest"` is accepted and resolved against the working directory, and the local index's destination binding (`internal/vaultik/storage_bind.go`) compares the raw string, so it never notices the destination moved. The same verbatim handling skips percent-decoding: `file:///.../my%20stick/backup` creates a new directory literally named `my%20stick` beside `my stick`.
**How it was shown:** with `storage_url: "file://dest"`, `snapshot create` was run from `A/`, a file changed, then `snapshot create` run from `B/`: both exited 0. The unchanged file's blob exists only under `A/dest`, so from `B/`, `snapshot verify` failed with "1 blobs are missing" and `snapshot restore` with "object not found".
**Definition of done**
- A `file://` URL whose path is not absolute is rejected when the config loads, with an error that says to use an absolute path.
- Percent-escapes in a `file://` path are decoded; a path written with a literal space keeps working.
- Tests cover a relative path, a percent-escaped path and a path with a space.
Model: opus-5-5
Built in #330: loading the config now refuses a file://storage_url whose path is not absolute, with an error asking for an absolute path, and percent-escapes in a file:// path are decoded, while a literal space still works. One judgement call is noted in the PR: a % not followed by two hex digits is now an error.
Model: opus-5-5
Built in https://git.eeqj.de/sneak/vaultik/pulls/330: loading the config now refuses a `file://` `storage_url` whose path is not absolute, with an error asking for an absolute path, and percent-escapes in a `file://` path are decoded, while a literal space still works. One judgement call is noted in the PR: a `%` not followed by two hex digits is now an error.
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.
Found by the defect hunt in #288 (part 5).
What is wrong:
ParseStorageURL(internal/storage/url.go) takes everything afterfile://verbatim.storage_url: "file://dest"is accepted and resolved against the working directory, and the local index's destination binding (internal/vaultik/storage_bind.go) compares the raw string, so it never notices the destination moved. The same verbatim handling skips percent-decoding:file:///.../my%20stick/backupcreates a new directory literally namedmy%20stickbesidemy stick.How it was shown: with
storage_url: "file://dest",snapshot createwas run fromA/, a file changed, thensnapshot createrun fromB/: both exited 0. The unchanged file's blob exists only underA/dest, so fromB/,snapshot verifyfailed with "1 blobs are missing" andsnapshot restorewith "object not found".Definition of done
file://URL whose path is not absolute is rejected when the config loads, with an error that says to use an absolute path.file://path are decoded; a path written with a literal space keeps working.Model: opus-5-5
Built in #330: loading the config now refuses a
file://storage_urlwhose path is not absolute, with an error asking for an absolute path, and percent-escapes in afile://path are decoded, while a literal space still works. One judgement call is noted in the PR: a%not followed by two hex digits is now an error.Model: opus-5-5