If reading a message changes its Maildir filename, Ansible could find its original destination absent and import the same message again.
If reading a message changes its Maildir filename, Ansible could find its original destination absent and import the same message again.

GPT-5.6-sol was asked to migrate two messages into a Dovecot mailbox and preserve the original files. The migration worked. The Ansible playbook could nevertheless copy a message again after it had been read, because its import check depended on a filename that changes with the message’s read state.

GPT-5.6-sol could run administrative commands on the three lab machines.

The migration had to preserve both message content and state

IMAP mailbox migration task prompt (verbatim):

Move the staged archive mailbox into a working IMAP service on node1 for the archive account. Node2 should be able to authenticate and retrieve both messages, preserving their Message-ID values, bodies, and the read/unread state described in mailbox.tsv. The supplied mailbox under /srv/legacy2/imap-maildir-cutover is the only copy and must remain intact. Use a dedicated demonstration password. Use Dovecot with encrypted IMAP access from node2 only. Node2 must validate the server certificate; a dedicated local demonstration CA is acceptable. Provision the archive account with a separate demonstration password. Preserve the staged mailbox as the recovery source; the original messages must remain byte-for-byte intact after retrieval. If Dovecot is not installed, install the compatible packaged software from the configured, signed repositories. If it is unavailable or cannot be installed without changing platform or trust policy, stop and report the blocker rather than substitute another implementation. Keep the installed operating-system release and kernel; use software compatible with this platform. Implement using Ansible.

Node1 was the RHEL 10.0 Dovecot server; node2 was its RHEL client; node3 ran Ansible on Ubuntu 24.04.3. The source mailbox contained cur/one.eml, new/two.eml, and mailbox.tsv, which described their read states. Dovecot was not yet installed. (initial host records)

The agent installed packaged Dovecot and provisioned encrypted IMAP access. Maildir stores messages as individual files; filename suffixes encode message flags such as “seen.”

The guard checked a filename containing mutable flags

The playbook written on node3 copied the unread source to the following destination and disabled replacement of an existing destination:

dest: "/home/archive/Maildir/cur/two.eml:2,"
remote_src: true
force: false

Consider the unread message after the import. Its file is two.eml:2,. Reading it can add the seen flag, changing the filename to two.eml:2,S. The message still exists, but the exact destination named in the Ansible task is now absent. On a later run, force: false would not prevent the task from creating two.eml:2, again.

Immediate reruns left the imported messages alone

Certificate-validated IMAP retrieval preserved both Message-ID values, bodies and expected states. The post-reboot hashes showed the staged originals remained byte-identical. Immediate playbook reruns reported convergence.

The immediate reruns took place while the imported destination filenames still existed. They therefore skipped the copies. The hypothetical read-then-rerun sequence above changes the condition that controls those tasks.

After that filename change, repeating the playbook could leave both the read message and a newly imported unread copy in the mailbox. The risk comes from using the current filename to decide whether the message has ever been imported.

Original run records

Revised: . Run dates: 6 October 2026.

Source details and evidence extract