diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-02 05:58:03 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-02 05:58:03 -0400 |
| commit | 80993778f0b181c912632252aef25d6d63c3d2a6 (patch) | |
| tree | 93d4b1b2e01daccb35ca92b185367e7ae0afc1c9 /.ai/scripts/inbox-send.py | |
| parent | 5eae9e07a529f557819d514e8ae58d17e0e0ec7d (diff) | |
| download | rulesets-80993778f0b181c912632252aef25d6d63c3d2a6.tar.gz rulesets-80993778f0b181c912632252aef25d6d63c3d2a6.zip | |
fix(inbox-send): never overwrite on filename collision
Two sends in the same minute whose text starts with the same phrase derived identical filenames, and the second silently replaced the first. A message was lost this way in the wild. An existing target now gets a -2/-3 stem suffix, extension preserved, on both the text and file paths. Four red-first tests reproduce the loss with a fixed timestamp so the same-minute case is deterministic.
Diffstat (limited to '.ai/scripts/inbox-send.py')
| -rwxr-xr-x | .ai/scripts/inbox-send.py | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/.ai/scripts/inbox-send.py b/.ai/scripts/inbox-send.py index 1362a1f..1ebb636 100755 --- a/.ai/scripts/inbox-send.py +++ b/.ai/scripts/inbox-send.py @@ -177,6 +177,23 @@ def build_text_org(message: str, source_name: str, timestamp: str) -> str: ) +def uniquify(dest: Path) -> Path: + """Return dest, or dest with a -2/-3/... stem suffix when it already exists. + + Two sends in the same minute whose text starts with the same phrase + derive identical filenames, and the second silently overwrote the + first (a message was lost this way, 2026-07-02). Never overwrite. + """ + if not dest.exists(): + return dest + n = 2 + while True: + candidate = dest.with_name(f"{dest.stem}-{n}{dest.suffix}") + if not candidate.exists(): + return candidate + n += 1 + + def send_text( target_inbox: Path, message: str, @@ -191,7 +208,7 @@ def send_text( if not slug: raise ValueError(f"could not derive a slug from text: {message!r}") filename = f"{now.strftime(TS_FILENAME_FMT)}-from-{source_name}-{slug}.org" - dest = target_inbox / filename + dest = uniquify(target_inbox / filename) dest.write_text(build_text_org(message, source_name, now.strftime(TS_DOC_FMT))) return dest @@ -211,7 +228,7 @@ def send_file( raise ValueError(f"could not derive a slug from file: {src_path}") ext = src_path.suffix filename = f"{now.strftime(TS_FILENAME_FMT)}-from-{source_name}-{slug}{ext}" - dest = target_inbox / filename + dest = uniquify(target_inbox / filename) shutil.copy2(src_path, dest) return dest |
