I use k9-mail on Android. It works perfectly fine, except for one thing: it does not support yearly based archives... However, k9-mail supports archives in general, thus you can easily set an archive folder and move the messages there.

That's were IMAPSIEVE comes into play - at least I thought so on first glance. Then I discovered, that it is actually not that easy to configure, as the documentation is very sparse. But fortunately, I got it working and want to document the steps I took.

For user and mailbox specific scripts, you also need to enable IMAP METADATA. Thus, the first step is to enable that.

Then you can enable IMAPSIEVE. The required parts are (for me on Debian):

in /etc/dovecot/conf.d/20-imap.conf set:

protocol imap {
    # ...
    mail_plugins = $mail_plugins imap_sieve
    # ...
}

and in /etc/dovecot/conf.d/90-sieve.conf set:

plugin {
    # This option should already be set when you configured sieve...
    sieve = file:~/sieve;active=~/.dovecot.sieve
    # ...
    # These two are the important bits for imapsieve:
    sieve_plugins = sieve_imapsieve

    imapsieve_url = sieve://your_managesieve_server:4190
    # ...
}

I simply assume that you have already configured managesieve and sieve correctly and to your needs. The imapsieve_url seems to be important and you have to configure the server URL to managesieve here. AFAIK it is only there to hint you the managesieve url though...

Now that you have configured all the important bits, you can test if the things are enabled. Run openssl s_client to connect to your IMAP like:

$ openssl s_client -crlf -connect  your_mail_server:993

you can login with a login your_username your_password

now, you should get a list of the CAPABILITIES of the server. Check that in the list there is METADATA and IMAPSIEVE=sieve://your_managesieve_server:4190.

Now, you can set mailbox specific sieve scripts, using the IMAP commandline. The important command here is SETMETADATA and GETMETADATA to verify. Information about these commands can be found in the RFC 5464.

Basically, you need to set the key /shared/imapsieve/script with the sieve script as value, per mailbox you want to filter.

For example, if you have uploaded a sieve script called archivefilter (this will physically be stored in %h/sieve/archivefilter.sieve if you configured the sieve option as I did), then you need to type the following command to activate it for the mailbox Archives:

a SETMETADATA "Archives" (/shared/imapsieve/script "archivefilter")

You can verify that by typing:

a GETMETADATA "Archives" /shared/imapsieve/script

if you are done, logout: a LOGOUT

Now for the sieve script itself. I want to redirect all messages which are moved into the Archives folder to Archives.YYYY - so that I can use the archives setting from k9-mail but keep my yearly archive.

So far, I was able to solve this using this sieve script:

require ["imapsieve", "environment", "date", "fileinto", "mailbox", "variables"];

# Rule for imapsieve, move messages from Archives to Archives.YEAR
if anyof (environment :is "imap.cause" "APPEND", environment :is "imap.cause" "COPY") {
    if date :matches "received" "year" "*" {
        fileinto :create "Archives.${1}";
        stop;
    }
    # No received date available... odd but OK... sort by currentdate:
    # (Not sure though if this can actually happen?)
    if currentdate :matches "year" "*" {
        fileinto :create "Archives.${1}";
        stop;
   }
}