tankslab.com/recall/source
tests/test_leftovers.py
148 lines, exactly as they ship in the download.
#!/usr/bin/env python3
"""
test_leftovers.py - each safety rule, proven able to refuse.
The cleanup step moves files on a stranger's machine. Every rule below has a case
that FAILS if the rule is removed, because a safety rail nobody has watched fail is
not a safety rail - and this package shipped a redactor with two leaks in it today,
found by someone else, so its author's reading of his own guards is not evidence.
python3 tests/test_leftovers.py
"""
from __future__ import annotations
import contextlib
import io
import os
import sys
import tempfile
from pathlib import Path
BIN = Path(__file__).resolve().parent.parent / "bin"
sys.path.insert(0, str(BIN))
import leftovers # noqa: E402
def main() -> int:
fails: list[str] = []
# Quarantine goes to HOME. A test that writes into the real one leaves litter on
# the machine of whoever runs it, which is precisely the manner this package is
# supposed to be an argument against.
sandbox = tempfile.mkdtemp()
os.environ["HOME"] = sandbox
quiet = contextlib.redirect_stdout(io.StringIO())
# RULE 5 - nothing is offered unless the import was verified.
with quiet:
r = leftovers.offer(Path("/tmp/nonexistent.db"), verified=False)
if not r["refused"]:
fails.append("RULE 5: offered cleanup without a verified import")
if r["moved"]:
fails.append("RULE 5: moved something without a verified import")
# RULE 6 - transcripts are never a candidate, at any privilege.
for p in (Path.home() / ".claude" / "projects",
Path.home() / ".claude" / "projects" / "anything" / "x.jsonl",
Path.home() / ".ssh",
Path.home() / ".claude" / "settings.json"):
if not leftovers._protected(p):
fails.append(f"RULE 6: {p} was NOT protected")
# RULE 4 - only positively identified things are candidates.
#
# The directory is taken from the source table rather than written here, so this
# test names nothing either.
import sources
dedicated = sources.dedicated_store_dirs()[0]
dedicated.mkdir(parents=True, exist_ok=True)
store = dedicated / "store.db"
store.write_bytes(b"x" * 10)
(dedicated / "logs").mkdir(exist_ok=True)
(dedicated / "logs" / "a.log").write_text("hi")
(dedicated / "someones-actual-work").mkdir(exist_ok=True)
(dedicated / "someones-actual-work" / "thesis.txt").write_text("do not touch")
(dedicated / "random.txt").write_text("neither")
got = {c["path"].name for c in leftovers.candidates(store)}
if "someones-actual-work" in got:
fails.append("RULE 4: offered an unidentified directory")
if "random.txt" in got:
fails.append("RULE 4: offered an unidentified file")
if "store.db" not in got or "logs" not in got:
fails.append(f"RULE 4: failed to identify what it SHOULD offer (got {got})")
# RULE 4, THE HARDER HALF - a NAME is not an identification.
#
# "archive", "backups" and "logs" are ordinary words people use for their own
# folders. When the database is somewhere the old tool never owned - which is
# exactly what `import --path` allows - those directories belong to the USER, and
# offering them while asserting they are "its backups" invites someone to type
# MOVE on their own data. Only the store and its own sidecars may be offered
# there. Without the gate this case hands back logs/archive/backups and the test
# goes red, which is the point of writing it.
loose = Path(tempfile.mkdtemp())
loose_store = loose / "old.db"
loose_store.write_bytes(b"x" * 10)
for name in ("logs", "archive", "backups"):
(loose / name).mkdir()
(loose / name / "mine.txt").write_text("the user's own work")
loose_got = {c["path"].name for c in leftovers.candidates(loose_store)}
strays = loose_got - {"old.db", "old.db-wal", "old.db-shm"}
if strays:
fails.append("RULE 4: outside the tool's own directory it offered "
f"name-matched folders it never identified: {sorted(strays)}")
if "old.db" not in loose_got:
fails.append("RULE 4: the database itself should still be offered (got "
f"{loose_got})")
# RULE 2 - the default is keep; only the typed word acts.
# " MOVE " is deliberately ABSENT from this list: the code strips whitespace, and
# someone who pastes the word with a space around it did type it. Rejecting that
# would be pedantry, not safety. Lowercase "move" IS rejected - the word has to be
# typed as shown, so it cannot be reached by a habitual "y".
for answer in ("", "y", "yes", "Y", "n", "no", "move", "MOVE!", "MOVEE", "delete"):
# NOTE the signature. offer() calls input_fn(prompt), so a lambda written as
# `lambda a=answer: a` receives the PROMPT and returns it - the answer under
# test is never used, nothing ever matches "MOVE", and the assertion passes
# no matter what the code does. That exact mistake was here, and mutation
# testing found it: weakening the guard to accept "" and "Y" did not turn
# this test red. A test that cannot fail is worse than no test.
with contextlib.redirect_stdout(io.StringIO()):
r = leftovers.offer(store, verified=True,
input_fn=lambda _prompt, a=answer: a)
if r["moved"]:
fails.append(f"RULE 2: answer {answer!r} MOVED something; only exact 'MOVE' may")
if not store.exists():
fails.append("RULE 2: the store was moved despite no confirmation")
# RULE 3 - the confirmed action MOVES, it does not delete.
# Rebuild the fixture: the rule-2 loop should have left it untouched, but this
# test must not depend on that to be meaningful.
store.write_bytes(b"x" * 10)
(dedicated / "logs").mkdir(exist_ok=True)
(dedicated / "logs" / "a.log").write_text("hi")
with contextlib.redirect_stdout(io.StringIO()):
r = leftovers.offer(store, verified=True, input_fn=lambda _prompt: "MOVE")
if not r["moved"]:
fails.append("RULE 3: exact 'MOVE' did not move anything - the guard is stuck shut")
else:
for src, dest in r["moved"]:
if src.exists():
fails.append(f"RULE 3: {src} still in place after a move")
if not dest.exists():
fails.append(f"RULE 3: {dest} does not exist - data was DESTROYED, not moved")
for f in fails:
print(" FAIL " + f, file=sys.stderr)
if fails:
print("\nLEFTOVERS SAFETY TEST FAILED", file=sys.stderr)
return 1
print("leftovers safety test OK - refuses without verification, protects transcripts,")
print(" offers only identified items (and only inside the tool's own directory),")
print(" defaults to keep, and moves rather than deletes")
return 0
if __name__ == "__main__":
sys.exit(main())