I finally figured out what's happening: v1.0 writes expunges as plain "expunged" records to dovecot.index.log file. v1.1 treats such records as "expunge requests", while the actual expunging is done by writing another "expunged (ext)" record.
With v1.1 dovecot.index file isn't always required, because its contents can be produced by reading dovecot.index.log file, assuming that is the first generated log file (prev log file sequence=0 in header). So what happens is that for some reason v1.1 doesn't read dovecot.index file, but reads dovecot.index.log file and ignores all expunge records. Maildir new/ and cur/ mtimes are all the same as in index files, so Dovecot doesn't bother reading the maildir. I was able to reproduce this by deleting dovecot.index file, but not without deleting it. So if it exists and you still have this problem, I don't really know why it wouldn't have read it.. Anyway, this fixes the problem: http://hg.dovecot.org/dovecot-1.1/rev/b776f2b8d827
signature.asc
Description: This is a digitally signed message part