diff options
Diffstat (limited to 'docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md')
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md index bcb6431..945aacd 100644 --- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md +++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md @@ -10278,3 +10278,100 @@ when it was written with `tr()`, and a comma joins a list the same way in Italian; a translatable separator is a string for a translator to get wrong for no gain. +## 184. New mail waits up to ten minutes, because sync is a fixed cron tick + +**Done 2026-09-13, outside this repository.** Built as `mail-watcher`, its own +project at `~/Programming/GIT/mail-watcher`, designed in that repository's +`docs/superpowers/specs/2026-09-13-mail-watcher-design.md` and confirmed running +on this machine as `~/bin/mail-watcher.sh --config ~/.config/mail-watcher/config.ini`. +Nothing in `src/` changed, which is the outcome this entry argued for: qtmaildir +is as ignorant of IMAP as it was, and the no-network-protocol rule is intact. + +**The three decisions this entry said could not be made by reading the repository +were made against the live servers.** A watcher of ours rather than a third-party +daemon, so there is no new SlackBuild to maintain; both hosts were probed and +advertise IDLE; and the connection count was the real constraint, since watching +all 50 synced folders would have sat one folder under the mail host's cap. The +answer was default-watch with an explicit exclude list, so the failure mode is +watching too much rather than silently missing mail, which matters because +server-side rules file mail directly into folders without touching INBOX. + +**Both constraints held.** The cron tick stays as a backstop, so a watcher that +dies silently degrades to the old ten minute wait rather than stopping mail; and +`/tmp/mbsync.lock` is still the shared mutex, so a triggered sync, a cron sync +and a click in qtmaildir serialise as before. + +**Item 174 was the blocker and was the right one.** `mailsync.sh` already writes +`~/.local/state/qtmaildir/syncstatus.json`, so the watcher had a tested reporting +channel to trigger into rather than making the application's guesswork about +external runs worse. + +The original entry follows. + +### The entry as it stood while open + +**Observed (user, 2026-08-29):** "the 10 minutes fixed tick has always bothered +me, I want the changes to my mail to be immediate, the 10 minutes mark is a +compromise, it had started at 30 min and was awful." + +**Split the want in two, because only half of it is open.** + +- **Outgoing is already immediate.** An edit arms `auto_sync_delay_ms`, 2 + seconds by default (item 71), so marking a message read reaches the server + without waiting for the tick. +- **Incoming is the gap.** Mail that arrives is invisible until the next cron + run of `mailsync.sh`, so the wait is uniform on [0, 10] minutes with a mean + of five. + +**Why a faster tick is not the fix.** Polling every minute is ten times the +connections and the server load for a mean wait of thirty seconds, and it is +still a poll: the wait is bounded by the interval however small it gets. The +answer to "tell me when something arrives" is IMAP IDLE, where the server holds +the connection and speaks first. + +**Where IDLE may live, and where it must not.** `AGENTS.md` states this +application does NO network protocol work at all: fetching and sending are +external commands, which is what keeps a mail client out of TLS, authentication +and an IMAP state machine. IDLE inside qtmaildir would break that rule outright +and is not on the table. + +It does not need to be inside. mbsync has no IDLE mode, being a batch syncer +that runs and exits; the tools that hold a connection and TRIGGER a sync are +separate programs (`goimapnotify` and the older `imapnotify` are the usual +ones). That shape fits the architecture exactly: the watcher replaces the cron +line, runs `mailsync.sh <channel>` on activity, and qtmaildir stays as ignorant +of IMAP as it is today. The script's flock still serialises a triggered sync +against a manual one. + +**Blocked on item 174**, and not merely sequenced after it. A watcher makes +syncs arrive at unpredictable times rather than on a known tick, which makes +the application's current guesswork about external runs worse. Item 174's +status file is the reporting channel this needs, and building it first means +the watcher has a tested one to write into. + +**Decisions needed before any code, none of which can be made by reading this +repository.** + +- **Which watcher**, or a small one of ours. A third-party daemon means a + SlackBuild in the `my-slackbuilds` repo and a package to maintain. +- **What the mail server supports.** IDLE is optional in IMAP, and a server + without it leaves polling as the only mechanism. +- **How many connections.** One per account per watched folder, held open + indefinitely; some servers cap concurrent connections. + +**Constraints.** + +- **Keep a slow cron tick as a backstop.** A held connection drops on network + sleep, a server restart or a laptop suspend, and a watcher that dies silently + stops mail altogether, which is worse than a ten minute wait. Belt and + braces: the watcher for latency, a slow tick so a dead watcher is survivable. +- **The lock is the shared mutex** and stays so. A triggered sync, a cron sync + and a click in qtmaildir must continue to serialise through + `/tmp/mbsync.lock`, or two mbsync runs corrupt Maildir UID state. +- **This is not a qtmaildir daemon.** A long-running qtmaildir service was + considered and rejected in the same conversation: it answers none of items + 174 or 125 better than a file does, and it adds a process that can wedge and + take mail delivery with it. What the user wants is a watcher, which is a + different thing in a different place. + + |
