Establish Dovecot’s writable virtual-Maildir contract #2

Closed
opened 2026-07-22 22:12:32 +00:00 by phg · 2 comments
Owner

Part of #1

Question

Against current official Dovecot documentation and source, what filesystem and configuration contract must a separate FUSE-backed Maildir namespace satisfy so Dovecot can discover folders, keep control/index metadata outside the generated message view where appropriate, assign stable UIDs and UIDVALIDITY, change standard Maildir flags, expunge messages, handle cur/new transitions, use either dot or slash mailbox hierarchy separators, and operate safely with FUSE caching and permissions?

Part of #1 ## Question Against current official Dovecot documentation and source, what filesystem and configuration contract must a separate FUSE-backed Maildir namespace satisfy so Dovecot can discover folders, keep control/index metadata outside the generated message view where appropriate, assign stable UIDs and UIDVALIDITY, change standard Maildir flags, expunge messages, handle cur/new transitions, use either dot or slash mailbox hierarchy separators, and operate safely with FUSE caching and permissions?
phg added the
wayfinder:research
label 2026-07-22 22:12:32 +00:00
Author
Owner

Claimed by Codex agent /root/research_dovecot_contract for primary-source research on 2026-07-23.

Claimed by Codex agent `/root/research_dovecot_contract` for primary-source research on 2026-07-23.
Author
Owner

Resolution

Use a separate private Dovecot Maildir namespace with mailbox_list_layout = fs. The FUSE mount exposes only complete <encoded-tag>/{cur,new,tmp} trees and immutable message bytes; persistent per-folder dovecot-uidlist/keyword control state and rebuildable indexes live in unique native writable paths outside the mount. Stable projection base names plus persistent control state preserve UIDVALIDITY and UIDs within each tag folder.

The writable surface is narrowly defined: standard Maildir flag renames (D, F, R, S, T), idempotent new/ to cur/ renames, and expunge unlink. Flag renames must be merged as deltas under a Source Maildir message lock and fanned out to every Message projection; returning ENOENT for a stale alias can silently lose a Dovecot flag change. Append/copy into tags, message-content writes, folder mutation, non-standard keywords, and multi-server access are unsupported.

Keep maildir_very_dirty_syncs = no and, for correctness with externally generated non-INBOX mailboxes, mailbox_list_index = no. Use zero negative-cache timeout, bounded entry/attribute timeouts, no writeback cache or cached readdir, and low-level FUSE invalidation notifications after mutations and watcher updates. Prefer the same mail UID/GID; if allow_other is needed, require default_permissions. The bare unmounted mountpoint must not be writable to Dovecot.

If Dovecot also exposes the Source Maildir directly, source rename/unlink must participate in its source dovecot-uidlist dotlock, requiring the exact source control path. Otherwise declare that Source Maildir delivery-only. This source-access mode must be explicit in the implementation specification.

Full cited findings: branch, commit 5b767c5, findings file.

## Resolution Use a separate private Dovecot Maildir namespace with `mailbox_list_layout = fs`. The FUSE mount exposes only complete `<encoded-tag>/{cur,new,tmp}` trees and immutable message bytes; persistent per-folder `dovecot-uidlist`/keyword control state and rebuildable indexes live in unique native writable paths outside the mount. Stable projection base names plus persistent control state preserve UIDVALIDITY and UIDs within each tag folder. The writable surface is narrowly defined: standard Maildir flag renames (`D`, `F`, `R`, `S`, `T`), idempotent `new/` to `cur/` renames, and expunge unlink. Flag renames must be merged as deltas under a Source Maildir message lock and fanned out to every Message projection; returning `ENOENT` for a stale alias can silently lose a Dovecot flag change. Append/copy into tags, message-content writes, folder mutation, non-standard keywords, and multi-server access are unsupported. Keep `maildir_very_dirty_syncs = no` and, for correctness with externally generated non-INBOX mailboxes, `mailbox_list_index = no`. Use zero negative-cache timeout, bounded entry/attribute timeouts, no writeback cache or cached readdir, and low-level FUSE invalidation notifications after mutations and watcher updates. Prefer the same mail UID/GID; if `allow_other` is needed, require `default_permissions`. The bare unmounted mountpoint must not be writable to Dovecot. If Dovecot also exposes the Source Maildir directly, source rename/unlink must participate in its source `dovecot-uidlist` dotlock, requiring the exact source control path. Otherwise declare that Source Maildir delivery-only. This source-access mode must be explicit in the implementation specification. Full cited findings: [branch](https://git.s1q.dev/phg/fuse-mail-dir-by-tag/src/branch/research/dovecot-writable-maildir-contract), [commit `5b767c5`](https://git.s1q.dev/phg/fuse-mail-dir-by-tag/commit/5b767c5), [findings file](https://git.s1q.dev/phg/fuse-mail-dir-by-tag/src/commit/5b767c5/docs/research/dovecot-writable-virtual-maildir-contract.md).
phg closed this issue 2026-07-22 22:26:06 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: phg/fuse-mail-dir-by-tag#2
No description provided.