1eef5e5ae37a33e4df287e385f48b283ec988734
Fixes the three defects PLAN.md section 6 lists. The previous-note glob is constrained to the date pattern, so a .sync-conflict- sibling can no longer be selected as the file to carry forward, which is the likeliest origin of how those conflicts spread. The retitle is line 1 only, so a body line like "meeting moved to 2026-09-08" is no longer silently advanced a day. The dead `&& cd -` is gone. Pull before the edit, push after. Error handling is shaped by the CrowdSec rules in section 5 rather than by generic retry logic: a 401 stops dead with a message, a 404 means the timer has not run yet so it creates once and never polls, and anything else degrades to editing the local copy. The offline fallback shells out to the same prune.py the server rollover uses, installed to ~/.local/lib/todo, so the two cannot drift. Since SFTPGo ignores If-Match, the precondition is enforced client side by comparing the ETag captured at pull against a HEAD before the PUT. A remote that moved mid-edit produces a .sync-conflict- sibling and a non-zero exit rather than an overwrite. Real merging is phase 5; this just makes phase 2 incapable of losing an edit. The credential comes from rbw and reaches curl over stdin, never argv, where any other user's ps could read it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PU5ZFfQFtDTFqqhvMTWdGH
Languages
Kotlin
66.8%
Python
18.7%
Shell
14.5%