Skip to content

v1.0.6

Choose a tag to compare

@github-actions github-actions released this 05 Jul 20:08
1c8b433

Silent-error audit: verified writes and honest reporting everywhere

v1.0.5 fixed archive/trash/move reporting success for messages that were never moved. This release is the result of auditing the whole CLI for that same class of bug — success reported without verifying the effect, and errors discarded on the way up. Every fix below landed test-first against a test server injected with the exact misbehavior (writes acknowledged but not applied, FETCH failing mid-stream, unstable SEARCH answers).

Fetch results are no longer trusted blindly

  • A FETCH that fails mid-stream now surfaces as an error. Previously the error was swallowed and the partial message list was returned as if complete, so extract, classify, summarize, digest, attachments, fetch-and-parse, unsubscribe, and reply composition could all silently operate on a truncated read.
  • Requested UIDs the server doesn't return no longer vanish. extract, unsubscribe, attachments, and summarize with --uid now emit a "type":"error" row for each UID that wasn't found (typo'd, already deleted, wrong mailbox) and count it in the summary's failed. Before, those UIDs simply produced no output at all.

Flag writes are verified like moves

  • mark-read and flag now verify every STORE. Work happens in chunks of 250 UIDs; each chunk is confirmed with UID SEARCH to be in the requested flag state, stragglers are retried once, and anything still wrong gets a "type":"error" row, a failed count in the summary, and a non-zero exit. Previously a single unverified UID STORE OK produced a success row for every input UID — including UIDs that don't exist.

Honest status reporting

  • cleanup-labels no longer reports "status":"ok" for labels it failed to delete. A rejected DELETE now emits "status":"failed" with the full error envelope (including how many messages had already been moved) and is counted in failed. Before, the failure was only a stderr warning while the NDJSON stream claimed success.
  • watch no longer emits phantom events. Each poll's UID SEARCH is re-run until two consecutive answers agree, so one flaky answer (seen with Proton Bridge's virtual All Mail) can no longer diff into a burst of fake expunge/new events.
  • apply-labels surfaces state-DB write failures instead of discarding them (a lost applied record silently re-applies labels on the next run), and import's APPEND error message now correctly labels the message index instead of calling it a UID.

Test infrastructure

  • imaptest gained WithMailboxWrapper and WithUserWrapper, letting tests decorate the in-memory server's backend with real-world misbehavior (acknowledged-but-ignored writes, mid-stream FETCH failures, unstable SEARCH results, rejected DELETEs). All of the above fixes are locked in by regression tests built on them.

Full Changelog: v1.0.5...v1.0.6