Re-review of #313, round 2:
- R1: a removal on another device than its kept copy, with the same
size and mtimes within 2 s, is protected when its inode is equal or its
path within its source is the same ("May be the same file reached
through another mount or share"), in the preview and again right before
each unlink. The job holds the kept copy open during the unlink, so on
Windows deleting the kept copy itself through another path fails.
- R2: a file's spellings are found by containment: every configured,
monitored, ComfyUI-output or listed folder whose stat identity is a
folder above the file. Parent spellings of nested sources and case
variants match; favorites move under every listed root holding the
file. Lookups stay index searches.
- m1: a failed unlink's row says the links now name the kept copy.
- m2: a volume with no file ids reads "Can't confirm this is a separate
file on this drive".
Final review of #313:
- C1: the duplicate find tells files apart by (st_dev, st_ino), so a
source listed twice, a symlinked source inside another and a hardlink
are one file. The preview and the job refuse a removal that
os.path.samestat matches with its kept copy.
- I1: each file's records move to its verified kept copy in one short
transaction before that file is unlinked; a failed move deletes
nothing and a failed unlink leaves the records on the identical kept
copy. The status line counts files removed and not removed.
- I2: links are looked up under every spelling of the source (the real
path, the configured and monitored folders, ComfyUI's output).
- I5: image tags join the kept copy as their union and the removed
copy's pending, undecided Needs review items are settled; the plan
says so.
- I3: the VACUUM disk check measures SQLite's real temporary folder.
- M1: the token is looked at again with no await before the job starts.
- M2: the backup decision is made once and handed to the job.
- M3: backups are linked into place; startup sweeps interrupted temps.
- M4: Optimize runs alone (new "exclusive" admission) and its plan says
the database is locked while VACUUM runs.
- M5: the reviewed duplicate merge is strict: collisions and Library
titles are protected, and errors roll back. The legacy cleanup is
unchanged.
- M7: 2,000 keep entries within a 1 MiB body. M8: event waits in tests.
- M9: the preview binds files by size, mtime and inode without hashing;
the job hashes right before each unlink.