-
released this
2026-08-12 15:58:48 -05:00 | 51 commits to main since this releasemove_messagenever worked, anddelete_messagewithoutpermanentnever worked
either, because it is a move. Both failed closed with "the server did not say where it
landed" for the whole life of M2. Fixed, and M2 is now verified against the live mailbox
— 27 checks, all passing.Fixed
-
The
COPYUIDwas read from the wrong place.IMAPClient.copy()returnsNoneon
iCloud; imaplib files the response code underuntagged_responses["COPYUID"]as
[b"<validity> <src> <dst>"], already stripped of the keyword. The parser was reading the
return value, found nothing, and — correctly — refused to expunge rather than guess a
handle. So the damage was a move that always failed rather than one that lost mail, which
is the direction that branch was written to fail in. -
A stale
COPYUIDcan no longer be mistaken for this copy's answer.
untagged_responsesaccumulates across commands on one connection, so the key is now
popped before the COPY as well as after. Left unguarded, a copy that produced no
response code could read the previous one's and mint a handle naming a different message —
worse than refusing, and silent.
Changed
- The test fake now models where the value actually lives. It previously returned a
COPYUIDstring fromcopy(), which no server does — that is precisely why the suite was
green while every real move failed. Two regression tests pin the real shape: one that the
handle comes fromuntagged_responses, one that a leftover entry is not read as this
copy's answer.
Notes
-
This is what the live checklist is for. 799 tests passed against a fake built on the
same wrong assumption as the code, which is the failure mode this project already had a
name for: the fakes agree with the code because the same person wrote both. The probe that
caught it drives the real tool layer against the real mailbox and lives inprobes/,
gitignored, because it names real folders. -
What the run established, beyond the fix: a moved message's new handle resolves to the
same message and reports the destination folder; the old handle refuses rather than
answering; no duplicate is left behind; an omittedupdate_messageargument leaves that
flag alone; both permanent-delete refusals leave the message intact; a default delete
lands in the trash folder and can be moved back out; and — the one that is silent and
unrecoverable when wrong —UID EXPUNGEremoved only the message it named, while a
neighbour flagged\Deletedby another client survived. -
Still owed for M2: the Trash default confirmed on a phone. The probe checks that the
handle names the configured trash folder, which is not the same as Apple showing the
message in the Trash a phone displays.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-