Recent changes to this wiki. Not to be confused with my history.

Complete source to the wiki is available on gitweb or by cloning this site.

more hardware notes
diff --git a/hardware/laptop.mdwn b/hardware/laptop.mdwn
index 4b2d26d4..4b389477 100644
--- a/hardware/laptop.mdwn
+++ b/hardware/laptop.mdwn
@@ -36,8 +36,8 @@ Modèles
 
 Comparateur: https://www.thelaptoplist.com/
 
-Frame work
-----------
+Framework
+---------
 
 <https://frame.work/>
 
@@ -74,6 +74,8 @@ Frame work
  * fan quiet when idle, but can be noisy when running
  * fingerprint reader
 
+https://www.phoronix.com/scan.php?page=article&item=framework-laptop&num=1
+
 GPD pocket
 ----------
 
@@ -442,6 +444,8 @@ large vendors like Dell, Lenovo or HP. They also have a rather bad
 policy on returns: dead pixels and screen defects are not accepted,
 for example.
 
+https://blogs.gnome.org/christopherdavis/2021/11/10/system76-how-not-to-collaborate/
+
 ### Galago pro
 
 <https://system76.com/laptops/galago>
@@ -627,6 +631,10 @@ http://www.ncix.com/detail/wd-blue-500b-internal-ssd-5d-136743.htm?promoid=2205
 
 Wifi card is soldered on, but i won't be using that much anyways.
 
+# Balthazar
+
+https://balthazar.space/
+
 CPU comparison
 --------------
 
diff --git a/hardware/tablet.mdwn b/hardware/tablet.mdwn
index 308483d6..40bac923 100644
--- a/hardware/tablet.mdwn
+++ b/hardware/tablet.mdwn
@@ -181,6 +181,14 @@ I ended up buying *two* of those (one for a teacher and one for me!
 is the old Android release and weird OS, but the reader is in
 generally excellent.
 
+### Onyx Mira
+
+Not an e-reader, but a monitor, similar to the Dasungs:
+
+<https://shop.boox.com/products/mira>
+
+In depth review: <https://www.youtube.com/watch?v=oBfWkxOfUfQ>
+
 reMarkable
 ----------
 
@@ -494,6 +502,11 @@ tablet](https://www.omgubuntu.co.uk/2019/01/pine-tab-linux-tablet) as well, runn
 Update: this is in [pre-order now](https://www.pine64.org/2020/05/15/may-update-pinetab-pre-orders-pinephone-qi-charging-more/), at 100$ a pop (plus 20$ for the
 magnetic keyboard), it looks real promising.
 
+
+## Jingpad A1
+
+https://en.jingos.com/jingpad-a1/
+
 Phones
 ======
 

fix typo, thanks marc laporte! :)
diff --git a/blog/2021-09-05-bullseye-upgrade-notes.mdwn b/blog/2021-09-05-bullseye-upgrade-notes.mdwn
index 1c312fe7..32407350 100644
--- a/blog/2021-09-05-bullseye-upgrade-notes.mdwn
+++ b/blog/2021-09-05-bullseye-upgrade-notes.mdwn
@@ -2,7 +2,7 @@
 
 It's major upgrade time again! The [Debian project](https://www.debian.org/) just published
 the [Debian 11 "bullseye"](https://www.debian.org/News/2021/20210814) release, and it's pretty awesome! This
-makes me realized that I have never written here about my [[peculiar
+makes me realize that I have never written here about my [[peculiar
 upgrade process|services/upgrades/bullseye]], and figured it was worth
 bringing that up to a wider audience.
 

silence ucf prompts as well
diff --git a/services/upgrades/bullseye.mdwn b/services/upgrades/bullseye.mdwn
index 89b3ac09..b9333352 100644
--- a/services/upgrades/bullseye.mdwn
+++ b/services/upgrades/bullseye.mdwn
@@ -105,8 +105,8 @@ connection.
 
  5. Actual upgrade run:
 
-        export DEBIAN_FRONTEND=noninteractive APT_LISTCHANGES_FRONTEND=none APT_LISTBUGS_FRONTEND=none &&
-        apt full-upgrade -y -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' &&
+        env DEBIAN_FRONTEND=noninteractive APT_LISTCHANGES_FRONTEND=none APT_LISTBUGS_FRONTEND=none UCF_FORCE_CONFFOLD=y \
+          apt full-upgrade -y -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' &&
         printf "\a" &&
         /home/anarcat/src/koumbit-scripts/vps/clean_conflicts &&
         printf "End of Step 5\a\n"

one more link
diff --git a/blog/2021-11-21-mbsync-vs-offlineimap.md b/blog/2021-11-21-mbsync-vs-offlineimap.md
index dd7f4466..19105f8f 100644
--- a/blog/2021-11-21-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-21-mbsync-vs-offlineimap.md
@@ -324,15 +324,15 @@ that can [rename files](https://afew.readthedocs.io/en/latest/move_mode.html#ren
 with `mbsync`. I had already been told about afew, but it's one more
 reason to standardize my notmuch hooks on that project, it looks like.
 
-Update: I have tried to use afew and found it has [significant
-performance issues](https://github.com/afewmail/afew/issues/319). It also has a completely different paradigm to
-what I am used to: it assumes all incoming mail has a `new` and lays
-its own tags on top of that (`inbox`, `sent`, etc). It can only move
-files from *one* folder at a time (see [this bug](https://github.com/afewmail/afew/issues/314)) which breaks my
-spam training workflow. In general, I sync my tags into folders
-(e.g. `ham`, `spam`, `sent`) and message flags (e.g. `inbox` is `F`,
-`unread` is "not `S`", etc), and afew is not well suited for this
-(although there are [hacks](https://github.com/afewmail/afew/issues/313) that [try](https://github.com/afewmail/afew/issues/317) to fix this). I have
+Update: I have tried to use afew and found it has [significant](https://github.com/afewmail/afew/issues/243)
+[performance issues](https://github.com/afewmail/afew/issues/319). It also has a completely different paradigm
+to what I am used to: it assumes all incoming mail has a `new` and
+lays its own tags on top of that (`inbox`, `sent`, etc). It can only
+move files from *one* folder at a time (see [this bug](https://github.com/afewmail/afew/issues/314)) which
+breaks my spam training workflow. In general, I sync my tags into
+folders (e.g. `ham`, `spam`, `sent`) and message flags (e.g. `inbox`
+is `F`, `unread` is "not `S`", etc), and afew is not well suited for
+this (although there are [hacks](https://github.com/afewmail/afew/issues/313) that [try](https://github.com/afewmail/afew/issues/317) to fix this). I have
 worked hard to make my tagging scripts idempotent, and it's something
 [afew doesn't currently have](https://github.com/afewmail/afew/issues/308). Still, it would be better to have
 that code in Python than bash, so maybe I should consider my options

report on afew
diff --git a/blog/2021-11-21-mbsync-vs-offlineimap.md b/blog/2021-11-21-mbsync-vs-offlineimap.md
index baa6e232..dd7f4466 100644
--- a/blog/2021-11-21-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-21-mbsync-vs-offlineimap.md
@@ -324,6 +324,20 @@ that can [rename files](https://afew.readthedocs.io/en/latest/move_mode.html#ren
 with `mbsync`. I had already been told about afew, but it's one more
 reason to standardize my notmuch hooks on that project, it looks like.
 
+Update: I have tried to use afew and found it has [significant
+performance issues](https://github.com/afewmail/afew/issues/319). It also has a completely different paradigm to
+what I am used to: it assumes all incoming mail has a `new` and lays
+its own tags on top of that (`inbox`, `sent`, etc). It can only move
+files from *one* folder at a time (see [this bug](https://github.com/afewmail/afew/issues/314)) which breaks my
+spam training workflow. In general, I sync my tags into folders
+(e.g. `ham`, `spam`, `sent`) and message flags (e.g. `inbox` is `F`,
+`unread` is "not `S`", etc), and afew is not well suited for this
+(although there are [hacks](https://github.com/afewmail/afew/issues/313) that [try](https://github.com/afewmail/afew/issues/317) to fix this). I have
+worked hard to make my tagging scripts idempotent, and it's something
+[afew doesn't currently have](https://github.com/afewmail/afew/issues/308). Still, it would be better to have
+that code in Python than bash, so maybe I should consider my options
+here.
+
 ## Stability issues
 
 The newer release in Debian bookworm (currently at 1.4.3) has

clarify that we know the fix by moving it a block up
diff --git a/blog/2021-11-21-mbsync-vs-offlineimap.md b/blog/2021-11-21-mbsync-vs-offlineimap.md
index 0f4f508b..baa6e232 100644
--- a/blog/2021-11-21-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-21-mbsync-vs-offlineimap.md
@@ -315,15 +315,15 @@ paths should be renamed, which is unfortunate, because I would need to
 change my script to adapt to `mbsync`, but I can't tell how just from
 reading the above.
 
+(A manual fix is actually to rename the file to remove the `U=` field:
+`mbsync` will generate a new one and then sync correctly.)
+
 Fortunately, someone else already fixed that issue: [afew](https://afew.readthedocs.io/), a
 notmuch tagging script (much puns, such hurt), has a [move mode](https://afew.readthedocs.io/en/latest/move_mode.html)
 that can [rename files](https://afew.readthedocs.io/en/latest/move_mode.html#rename) correctly, specifically designed to deal
 with `mbsync`. I had already been told about afew, but it's one more
 reason to standardize my notmuch hooks on that project, it looks like.
 
-(A manual fix is actually to rename the file to remove the `U=` field:
-`mbsync` will generate a new one and then sync correctly.)
-
 ## Stability issues
 
 The newer release in Debian bookworm (currently at 1.4.3) has

more languages
diff --git a/blog/2021-11-21-mbsync-vs-offlineimap.md b/blog/2021-11-21-mbsync-vs-offlineimap.md
index 48e9e8a6..0f4f508b 100644
--- a/blog/2021-11-21-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-21-mbsync-vs-offlineimap.md
@@ -903,7 +903,8 @@ performance, I have not looked any deeper in those discrepancies.
 Those are all the options I have considered, in alphabetical order
 
  * [doveadm-sync](https://wiki2.dovecot.org/Tools/Doveadm/Sync): requires dovecot on both ends, can tunnel over
-   SSH, [may have performance issues in incremental sync](https://anarc.at/blog/2021-06-29-another-mail-crash/#comment-2e8364e113d1d7b8415c8652f217cfff)
+   SSH, [may have performance issues in incremental sync](https://anarc.at/blog/2021-06-29-another-mail-crash/#comment-2e8364e113d1d7b8415c8652f217cfff), written
+   in C
  * [fdm](https://github.com/nicm/fdm): fetchmail replacement, IMAP/POP3/stdin/Maildir/mbox,NNTP
    support, SOCKS support (for Tor), complex rules for delivering to
    specific mailboxes, adding headers, piping to commands,
@@ -913,7 +914,7 @@ Those are all the options I have considered, in alphabetical order
    incremental runs, classification rules, Python
  * [interimap](https://guilhem.org/interimap/): syncs two IMAP servers, [apparently faster](https://guilhem.org/interimap/benchmark.html) than
    `doveadm` and `offlineimap`, but requires running an IMAP server
-   locally
+   locally, Perl
  * [isync/mbsync](http://isync.sf.net/): TLS client certs and SSH tunnels, fast,
    incremental, IMAP/POP/Maildir support, multiple mailbox, trash and
    recursion support, and generally has good words from multiple
@@ -923,12 +924,12 @@ Those are all the options I have considered, in alphabetical order
    (e.g. ssh), diff/patch system, requires binary on both ends,
    mentions UUCP in the manpage, mentions `rsmtp` which is a nice name
    for `rsendmail`. not evaluated because it seems awfully complex to
-   setup
+   setup, Haskell
  * [nncp](http://www.nncpgo.org/): treat the local spool as another mail server, not really
-   compatible with my "multiple clients" setup
+   compatible with my "multiple clients" setup, Golang
  * [offlineimap3](https://github.com/OfflineIMAP/offlineimap3): requires IMAP, used the py2 version in the past,
    might just still work, first sync painful (IIRC), ways to tunnel
-   over SSH, review above
+   over SSH, review above, Python
 
 Most projects were not evaluated due to lack of time.
 

finished another read/edit, phew
diff --git a/blog/2021-11-21-mbsync-vs-offlineimap.md b/blog/2021-11-21-mbsync-vs-offlineimap.md
index 6976ace2..48e9e8a6 100644
--- a/blog/2021-11-21-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-21-mbsync-vs-offlineimap.md
@@ -72,11 +72,31 @@ figure out right now:
 
 Interesting that `rsync` manages to almost beat a plain `tar` on file
 transfer, I'm actually surprised by how well it performs here,
-considering there are many little files to transfer. But then again,
-this maybe is exactly where `rsync` shines: while `tar` needs to glue
-all those little files together, `rsync` can just directly talk to the
-other side and tell it to do live changes. Something to look at in
-another article maybe?
+considering there are many little files to transfer. 
+
+(But then again, this maybe is exactly where `rsync` shines: while
+`tar` needs to glue all those little files together, `rsync` can just
+directly talk to the other side and tell it to do live
+changes. Something to look at in another article maybe?)
+
+Since both ends are NVMe drives, those should easily saturate a
+gigabit link. And in fact, a backup of the server mail spool achieves
+much faster transfer rate on disks:
+
+    anarcat@marcos:~$ tar fc - Maildir | pv -s 13G > Maildir.tar
+    15,0GiO 0:01:57 [ 131MiB/s] [===================================] 115%
+
+That's 131Mi**byyte** per second, vastly faster than the gigabit
+link. The client has similar performance:
+
+    anarcat@angela:~(main)$ tar fc - Maildir | pv -s 17G > Maildir.tar
+    16,2GiO 0:02:22 [ 116MiB/s] [==================================] 95%
+
+So those disks should be able to saturate a gigabit link, and they are
+not the bottleneck on fast links. Which begs the question of what is
+blocking performance of a similar transfer over the gigabit link, but
+that's another question altogether, because no sync program ever
+reaches the above performance anyways.
 
 Finally, note that when I migrated to SMD, I wrote a small
 [[performance
@@ -96,7 +116,7 @@ full folder support, and "trash" functionality.
 
 ## Complex configuration file
 
-I am using this `.mbsyncrc` configuration file:
+I started with this `.mbsyncrc` configuration file:
 
     SyncState *
     Sync New ReNew Flags
@@ -166,32 +186,16 @@ situation.
 
 ## Stellar performance
 
-The full sync of my 300,000+ messages (12GB) took 56 minutes and 6
-seconds, which is impressive.
+A transfer of the entire mail spool takes 56 minutes and 6 seconds,
+which is impressive.
 
 It's not quite "line rate": the resulting mail spool was 12GB (which
 is a problem, see below), which turns out to be about 29Mbit/s and
-therefore not maxing the gigabit link. That said, it's possible disks
-were the bottleneck on either end, although I'd be surprised by that:
-both are NVMe drives, so that should easily saturate a gigabit
-link. And in fact, a remote backup of the mail spool achieves much
-faster transfer rate on disks, so I do not believe the server is to
-blame here:
-
-    anarcat@marcos:~$ tar fc - Maildir | pv -s 13G > Maildir.tar
-    15,0GiO 0:01:57 [ 131MiB/s] [===================================] 115%
-
-That's 131Mi**byyte** per second, vastly faster than the gigabit
-link. The client has similar performance:
-
-    anarcat@angela:~(main)$ tar fc - Maildir | pv -s 17G > Maildir.tar
-    16,2GiO 0:02:22 [ 116MiB/s] [==================================] 95%
-
-So yes, those disks should be able to saturate a gigabit link, they
-are not the bottleneck.
+therefore not maxing the gigabit link, and an order of magnitude
+slower than `rsync`.
 
 The incremental runs are roughly 2 seconds, which is even *more*
-impressive:
+impressive, as that's actually *faster* than `rsync`:
 
     ===> multitime results
     1: mbsync -a
@@ -201,21 +205,21 @@ impressive:
     sys         0.338       0.033       0.268       0.341       0.387    
 
 Those tests were performed with isync 1.3.0-2.2 on Debian
-bullseye. Tests with a newer isync release failed because of a
-corrupted message that triggered [bug 999804](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=999804). Running 1.4.3 under
-valgrind works around the bug, but adds a 50% performance cost, the
-full sync running in 1h35m.
+bullseye. Tests with a newer isync release originally failed because
+of a corrupted message that triggered [bug 999804](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=999804) (see
+below). Running 1.4.3 under valgrind works around the bug, but adds a
+50% performance cost, the full sync running in 1h35m.
 
-A test with 1.4.3 yielded many crashes and stability issues (see
-below). Performance is fairly similar, considering that the new sync
-included the `register` folder with 4000 messages:
+Once the upstream patch is applied, performance with 1.4.3 is fairly
+similar, considering that the new sync included the `register` folder
+with 4000 messages:
 
     120.74user 213.19system 59:47.69elapsed 9%CPU (0avgtext+0avgdata 105420maxresident)k
     29128inputs+28284376outputs (0major+45711minor)pagefaults 0swaps
 
-That is ~13GB in ~60 minutes, which gives us 28.3Mbps, fairly close to
-the 1.3 benchmark. Incrementals are also pretty similar, again
-considering the double-connect cost:
+That is ~13GB in ~60 minutes, which gives us 28.3Mbps. Incrementals
+are also pretty similar to 1.3.x, again considering the double-connect
+cost:
 
     ===> multitime results
     1: mbsync -a
@@ -225,30 +229,32 @@ considering the double-connect cost:
     sys         0.322       0.024       0.284       0.320       0.365
 
 Those tests were all done on a Gigabit link, but what happens on a
-slower link? My server uplink is surprisingly slow: 25/6 Mbps. There
-`mbsync` doesn't far as well, and is worse than the SMD baseline:
+slower link? My server uplink is slow: 25 Mbps down, 6 Mbps up. There
+`mbsync` is worse than the SMD baseline:
 
-    1.80user 0.54system 0:35.70elapsed 6%CPU (0avgtext+0avgdata 25984maxresident)k
-    0inputs+0outputs (0major+19315minor)pagefaults 0swaps
+    ===> multitime results
+    1: mbsync -a
+    Mean        Std.Dev.    Min         Median      Max
+    real        31.531      0.724       30.764      31.271      33.100      
+    user        1.858       0.125       1.721       1.818       2.131       
+    sys         0.610       0.063       0.506       0.600       0.695       
 
-That's 35 seconds for a sync, which is an order of magnitude slower
+That's 30 seconds for a sync, which is an order of magnitude slower
 than SMD.
 
-TODO: multitime
-
 ## Great user interface
 
 Compared to OfflineIMAP and (ahem) SMD, the `mbsync` UI is kind of neat:
 
     anarcat@angela:~(main)$ mbsync -a
     Notice: Master/Slave are deprecated; use Far/Near instead.
-    C: 1/2  B: 204/205  F: +0/0 *0/0 #0/0  N: +1/2 *0/0 #0/0
+    C: 1/2  B: 204/205  F: +0/0 *0/0 #0/0  N: +1/200 *0/0 #0/0
 
-(Note that nice [switch away from slavery](https://github.com/get-woke/woke) too.)
+(Note that nice [switch away from slavery-related terms](https://github.com/get-woke/woke) too.)
 
-The display is minimalist, and yet informative. It's not obvious from
-the start what it does, but the manpage is instructive at least on
-that, and you get used to it:
+The display is minimal, and yet informative. It's not obvious what
+does mean at first glance, but the manpage is useful at least for
+clarifying that:
 
 > This represents the cumulative progress over **channels**,
 > **boxes**, and messages affected on the **far** and **near** side,
@@ -263,14 +269,14 @@ In other words:
  * `C 2/2`: channels done/total (2 done out of 2)
  * `B 204/205`: mailboxes done/total (204 out of 205)
  * `F`: changes on the far side
- * `N: +1/2 *0/0 #0/0`: changes on the "near" side:
-   * `+1/2`: one out of two messages downloaded
+ * `N: +10/200 *0/0 #0/0`: changes on the "near" side:
+   * `+10/200`: 10 out of 200 messages downloaded
    * `*0/0`: no flag changed
    * `#0/0`: no message deleted
 
-I like it. It does not, unfortunately, show up when you run it in
-systemd, which is a bit annoying as I like to see mail traffic in the
-logs.
+You get used to it, in a good way. It does not, unfortunately, show up
+when you run it in systemd, which is a bit annoying as I like to see
+a summary mail traffic in the logs.
 
 ## Interoperability issue
 
@@ -333,15 +339,15 @@ issues. The [Debian security tracker](https://security-tracker.debian.org) has o
 isync, but the above issues show there could be many more.
 
 Reading the source code certainly did not make me very comfortable
-with trusting it with arbitrary data. I have considered sandboxing it
-with systemd (below) but having systemd run as a `--user` process
-makes that difficult. I have also considered using an [apparmor
-profile](https://github.com/krathalan/apparmor-profiles/blob/master/profiles/mbsync) but that is not trivial because we need to allow SSH and
-only some parts of it...
+with trusting it with untrusted data. I considered sandboxing it with
+systemd (below) but having systemd run as a `--user` process makes
+that difficult. I also considered using an [apparmor profile](https://github.com/krathalan/apparmor-profiles/blob/master/profiles/mbsync) but
+that is not trivial because we need to allow SSH and only some parts
+of it...
 

(Diff truncated)
more wording fixes, still not done editing it seems
diff --git a/blog/2021-11-21-mbsync-vs-offlineimap.md b/blog/2021-11-21-mbsync-vs-offlineimap.md
index 83f1f888..6976ace2 100644
--- a/blog/2021-11-21-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-21-mbsync-vs-offlineimap.md
@@ -71,16 +71,20 @@ figure out right now:
     12,1GiO 0:05:17 [39,0MiB/s] [===================================================================> ] 92%
 
 Interesting that `rsync` manages to almost beat a plain `tar` on file
-transfer, I'm actually surprised by how fast it performs here,
-considering there are many little files to transfer.
+transfer, I'm actually surprised by how well it performs here,
+considering there are many little files to transfer. But then again,
+this maybe is exactly where `rsync` shines: while `tar` needs to glue
+all those little files together, `rsync` can just directly talk to the
+other side and tell it to do live changes. Something to look at in
+another article maybe?
 
 Finally, note that when I migrated to SMD, I wrote a small
 [[performance
 comparison|services/mail/syncmaildir#performance-comparison]] that
 could be interesting here. It show SMD to be faster than OfflineIMAP,
 but not as much as we see here. In fact, it looks like OfflineIMAP
-slowed down significantly since I last did tests on it, but this could
-be due to my larger mail spool.
+slowed down significantly since then (May 2018), but this could be due
+to my larger mail spool as well.
 
 # mbsync
 
@@ -152,12 +156,13 @@ needs colons, like:
 
 Why? That seems just too complicated. I also found that sections are
 not clearly identified: `IMAPAccount` and `Channel` mark section
-beginnings, for example. There are also weird ordering issues: the
+beginnings, for example, which is not at all obvious until you learn
+about `mbsync`'s internals. There are also weird ordering issues: the
 `SyncState` option needs to be before `IMAPAccount`, presumably
 because it's global.
 
-Using a more standard format like .INI or TOML would improve things
-greatly here.
+Using a more standard format like .INI or TOML could improve that
+situation.
 
 ## Stellar performance
 
diff --git a/blog/2021-11-21-one-last-smd-crash.md b/blog/2021-11-21-one-last-smd-crash.md
index 9ba67e1c..dd76d765 100644
--- a/blog/2021-11-21-one-last-smd-crash.md
+++ b/blog/2021-11-21-one-last-smd-crash.md
@@ -80,12 +80,14 @@ constantly restart `mbsync` with a silly command like:
     nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: UID=19288: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288) (read reason=)
     nov 16 13:53:08 marcos dovecot[3520770]: imap-login: Panic: epoll_ctl(del, 7) failed: Bad file descriptor
 
-The second problem is much harder to fix, because dovecot does *not*
-recover automatically. 
+This second problem is much harder to fix, because dovecot does *not*
+recover automatically. This is Dovecot complaining that the cached
+size (the `S=` field, but also present in Dovecot's metadata files)
+doesn't match the file size.
 
 ## Workaround
 
-So I read a lot pf the [Dovecot documentation on the maildir
+So I read a lot of the [Dovecot documentation on the maildir
 format](https://doc.dovecot.org/admin_manual/mailbox_formats/maildir/), and wrote an extensive [fix script](https://gitlab.com/anarcat/scripts/-/blob/main/dovecot-fix-size-cache.py) for those two
 errors. The script worked and `mbsync` was able to sync the entire mail
 spool.
@@ -116,8 +118,8 @@ Unfortunately, the first `mbsync` was incomplete as it was missing about
 As it turns out, `mbsync` was not at fault here either: this was yet
 more mail spool corruption.
 
-It's actually 26 folders with different sizes, which can be found
-with:
+It's actually 26 folders (out of 205) with inconsistent sizes, which can
+be found with:
 
     for folder in * .[^.]* ; do 
       printf "%s\t%d\n" $folder $(find "$folder" -type f -a \! -name '.*' | wc -l );
@@ -184,16 +186,16 @@ After moving those files around, we still have 4,000 message missing:
     385053
 
 The problem is that *those* 4,000 missing mails are harder to
-track. Take, for example, `.Archives.2011`, which has a single messge
+track. Take, for example, `.Archives.2011`, which has a single message
 missing, out of 3,582. And the files are not identical: the checksums
 don't match after going through the IMAP transport, so we can't use a
-tool like [hashdeep](http://md5deep.sourceforge.net/) to compare the trees and find why that one
+tool like [hashdeep](http://md5deep.sourceforge.net/) to compare the trees and find why any single
 file is missing.
 
 ## "register" folder
 
 One big chunk of the 4,000, however, is a special folder called
-`register` in my spool, which I was syncing separately (see [Securing
+`register` in my spool, which I am syncing separately (see [Securing
 registration email](https://anarc.at/blog/2019-03-20-locking-down-registration-mail/) for details on that setup). That actually
 covers 3,700 of those messages, so I actually have a more modest 300
 messages to figure out, after (easily!) configuring `mbsync` to sync
@@ -245,14 +247,16 @@ Argh. After *more* digging, I have found 131 mails in the `tmp/`
 directories of the *client*'s mail spool. Mysterious! On the server
 side, it's even *more* files, and *not* the same ones. Possible that
 those were mails that were left there during a failed delivery of some
-sort, during a power failure or some sort of crash? Who knows.
+sort, during a power failure or some sort of crash? Who knows. It
+could be another race condition in SMD if it runs while mail is being
+delivered in `tmp/`...
 
 The first thing to do with those is to cleanup a bunch of empty files
 (21 on angela):
 
     find .[^.]*/tmp -type f -empty -delete
 
-As *that* turns out, they are *all* duplicates, in the sense that
+As it turns out, they are *all* duplicates, in the sense that
 notmuch can easily find a copy of files with the same message ID in
 its database. In other words, this hairy command returns nothing
 
@@ -292,15 +296,15 @@ entire directory and starting from scratch, I end up with:
 
 That is: even *more* messages missing (now 37). Sigh.
 
-Hopefully, this is something [notmuch](https://notmuchmail.org/) will be able to help with:
+Thankfully, this is something [notmuch](https://notmuchmail.org/) can help with:
 it can index all files by `Message-ID` (which I learned is
 case-insensitive, yay) and tell us which messages don't make it
 through.
 
 Considering the corruption I found in the mail spool, I wouldn't be
-the least surprised those messages are just skipped by the IMAP server
-because of corruption. Unfortunately, there's nothing on the Dovecot
-server logs that would explain the discrepancy.
+the least surprised those messages are just skipped by the IMAP
+server. Unfortunately, there's nothing on the Dovecot server logs that
+would explain the discrepancy.
 
 Here again, notmuch comes to the rescue. We can list all message IDs
 to figure out that discrepancy:
@@ -356,7 +360,7 @@ list..."), it seems fairly harmless to ignore those.
 # Conclusion
 
 As we'll see in the [[next article|2021-11-21-mbsync-vs-offlineimap]],
-SMD has stellar performance, but this comes at a huge cost: it
+SMD has stellar performance. But that comes at a huge cost: it
 accesses the mail storage directly. This can (and has) created
 *significant* problems on the mail server. It's unclear exactly *why*
 those things happen, but Dovecot expects a particular storage format

wording fixes, incomplete
diff --git a/blog/2021-11-21-one-last-smd-crash.md b/blog/2021-11-21-one-last-smd-crash.md
index 042d765a..9ba67e1c 100644
--- a/blog/2021-11-21-one-last-smd-crash.md
+++ b/blog/2021-11-21-one-last-smd-crash.md
@@ -48,32 +48,25 @@ alternatives, which led me down a lot of rabbit holes.
 
 Reviewing my [[previous mail crash
 documentation|blog/2021-06-29-another-mail-crash]], it seems most
-solution involve talking to an IMAP server, so I figured I would just
+solutions involve talking to an IMAP server, so I figured I would just
 do that. Wanting to try something new, i gave [isync](https://isync.sourceforge.io/) (AKA
 `mbsync`) a try. Oh dear, I did not expect how much trouble just
-talking to my IMAP server would be. It's not isync's fault, for what
-it's worth, but it's the primary tool I used to debug things, and
-served me well in that regard.
+talking to my IMAP server would be, which wasn't not isync's fault,
+for what that's worth. It was the primary tool I used to debug things,
+and served me well in that regard.
 
 # Mailbox corruption
 
 The first thing I found out is that certain messages in the IMAP spool
 were corrupted. `mbsync` would stop on a `FETCH` command and Dovecot
-would give me those errors on the server side:
+would give me those errors on the server side.
+
+## "wrong W value"
 
     nov 16 15:31:27 marcos dovecot[3621800]: imap(anarcat)<3630489><wAmSzO3QZtfAqAB1>: Error: Mailbox junk: Maildir filename has wrong W value, renamed the file from /home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495,W=2578:2,S to /home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495:2,S
     nov 16 15:31:27 marcos dovecot[3621800]: imap(anarcat)<3630489><wAmSzO3QZtfAqAB1>: Error: Mailbox junk: Deleting corrupted cache record uid=1582: UID 1582: Broken virtual size in mailbox junk: read(/home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495,W=2578:2,S): FETCH BODY[] got too little data: 2540 vs 2578
 
-and:
-
-    nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: UID=19288: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288) (read reason=mail stream)
-    nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: Deleting corrupted cache record uid=19288: UID 19288: Broken physical size in mailbox Sent: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288)
-    nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: UID=19288: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288) (read reason=)
-    nov 16 13:53:08 marcos dovecot[3520770]: imap-login: Panic: epoll_ctl(del, 7) failed: Bad file descriptor
-
-## "wrong W value"
-
-At least the first error was automatically healed by Dovecot (by
+At least this first error was automatically healed by Dovecot (by
 renaming the file without the `W=` flag). The problem is that the
 `FETCH` command fails and `mbsync` exits noisily. So you need to
 constantly restart `mbsync` with a silly command like:
@@ -82,13 +75,17 @@ constantly restart `mbsync` with a silly command like:
 
 ## "cached message size larger than expected"
 
+    nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: UID=19288: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288) (read reason=mail stream)
+    nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: Deleting corrupted cache record uid=19288: UID 19288: Broken physical size in mailbox Sent: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288)
+    nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: UID=19288: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288) (read reason=)
+    nov 16 13:53:08 marcos dovecot[3520770]: imap-login: Panic: epoll_ctl(del, 7) failed: Bad file descriptor
+
 The second problem is much harder to fix, because dovecot does *not*
-recover automatically. The above loop was taking too long: one full
-IMAP roundtrip (with authentication) for every corrupt message...
+recover automatically. 
 
 ## Workaround
 
-So I read a lot on the [Dovecot documentation on the maildir
+So I read a lot pf the [Dovecot documentation on the maildir
 format](https://doc.dovecot.org/admin_manual/mailbox_formats/maildir/), and wrote an extensive [fix script](https://gitlab.com/anarcat/scripts/-/blob/main/dovecot-fix-size-cache.py) for those two
 errors. The script worked and `mbsync` was able to sync the entire mail
 spool.

capitalisation and quoting
diff --git a/blog/2021-11-21-mbsync-vs-offlineimap.md b/blog/2021-11-21-mbsync-vs-offlineimap.md
index c8da7ec1..83f1f888 100644
--- a/blog/2021-11-21-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-21-mbsync-vs-offlineimap.md
@@ -233,7 +233,7 @@ TODO: multitime
 
 ## Great user interface
 
-Compared to OfflineIMAP and (ahem) SMD, the mbsync UI is kind of neat:
+Compared to OfflineIMAP and (ahem) SMD, the `mbsync` UI is kind of neat:
 
     anarcat@angela:~(main)$ mbsync -a
     Notice: Master/Slave are deprecated; use Far/Near instead.
@@ -307,7 +307,7 @@ reading the above.
 Fortunately, someone else already fixed that issue: [afew](https://afew.readthedocs.io/), a
 notmuch tagging script (much puns, such hurt), has a [move mode](https://afew.readthedocs.io/en/latest/move_mode.html)
 that can [rename files](https://afew.readthedocs.io/en/latest/move_mode.html#rename) correctly, specifically designed to deal
-with mbsync. I had already been told about afew, but it's one more
+with `mbsync`. I had already been told about afew, but it's one more
 reason to standardize my notmuch hooks on that project, it looks like.
 
 (A manual fix is actually to rename the file to remove the `U=` field:
@@ -322,7 +322,7 @@ found at least three distinct crashes that could be double-free bugs
 "[which might be exploitable in the worst case](https://sourceforge.net/p/isync/mailman/message/37385942/)", not a reassuring
 prospect.
 
-The thing is: mbsync is really fast, but the downside of that is that
+The thing is: `mbsync` is really fast, but the downside of that is that
 it's written in C, and with that comes a whole set of security
 issues. The [Debian security tracker](https://security-tracker.debian.org) has only [three CVEs](https://security-tracker.debian.org/tracker/source-package/isync) on
 isync, but the above issues show there could be many more.
@@ -340,7 +340,7 @@ issues, including on a full sync from scratch.
 
 ## Automation with systemd
 
-[The Arch wiki](https://wiki.archlinux.org/title/Isync#Calling_mbsync_automatically) has instructions on how to setup mbsync as a
+[The Arch wiki](https://wiki.archlinux.org/title/Isync#Calling_mbsync_automatically) has instructions on how to setup `mbsync` as a
 systemd service. It suggests using the `--verbose` (`-V`) flag which
 is a little intense here, as it outputs 1444 lines of messages.
 
@@ -469,7 +469,7 @@ Run a full sync on the client, with the `Inbox` pointing at
     mbsync -a
 
 This should take an hour on a gigabit link, much longer on
-remote. When that is done, move the mbsync `Maildir` in place:
+remote. When that is done, move the `mbsync` `Maildir` in place:
 
     mv Maildir Maildir-smd
     mv Maildir-mbsync Maildir
@@ -614,7 +614,7 @@ maintained. The main author moved on to a different project,
 but never seemed to get back to the OfflineIMAP feature
 set. Thankfully, a new team of volunteers ported OfflineIMAP to Python
 3 and we can now test that new version to see if it is an improvement
-over mbsync.
+over `mbsync`.
 
 ## Crash on full sync
 
@@ -811,7 +811,7 @@ Command exited with non-zero status 1
 ```
 
 This is 8h31m for transferring 12G, which is around 3.1Mbit/s. That is
-*nine* times slower than mbsync, almost an order of magnitude!
+*nine* times slower than `mbsync`, almost an order of magnitude!
 
 Now that we have a full sync, we can test incremental
 synchronization. That is also much slower:
@@ -844,7 +844,7 @@ The OfflineIMAP mail spool is missing quite a few messages as well:
 ... although that's probably *all* either new messages or the
 `register` folder, so OfflineIMAP might actually be in a better
 position there. But digging in more, it seems like the actual
-per-folder diff is fairly similar to mbsync: a few messages missing
+per-folder diff is fairly similar to `mbsync`: a few messages missing
 here and there. Considering OfflineIMAP's instability and poor
 performance, I have not looked any deeper in those discrepancies.
 
diff --git a/blog/2021-11-21-one-last-smd-crash.md b/blog/2021-11-21-one-last-smd-crash.md
index e09eff2e..042d765a 100644
--- a/blog/2021-11-21-one-last-smd-crash.md
+++ b/blog/2021-11-21-one-last-smd-crash.md
@@ -55,7 +55,7 @@ talking to my IMAP server would be. It's not isync's fault, for what
 it's worth, but it's the primary tool I used to debug things, and
 served me well in that regard.
 
-# mailbox corruption
+# Mailbox corruption
 
 The first thing I found out is that certain messages in the IMAP spool
 were corrupted. `mbsync` would stop on a `FETCH` command and Dovecot
@@ -90,7 +90,7 @@ IMAP roundtrip (with authentication) for every corrupt message...
 
 So I read a lot on the [Dovecot documentation on the maildir
 format](https://doc.dovecot.org/admin_manual/mailbox_formats/maildir/), and wrote an extensive [fix script](https://gitlab.com/anarcat/scripts/-/blob/main/dovecot-fix-size-cache.py) for those two
-errors. The script worked and mbsync was able to sync the entire mail
+errors. The script worked and `mbsync` was able to sync the entire mail
 spool.
 
 And no, [rebuilding the index files](https://dovecot.org/pipermail/dovecot/2019-June/116227.html) didn't work. Also tried
@@ -108,7 +108,7 @@ replica of the mail spool).
 
 # Incoherence between Maildir and IMAP
 
-Unfortunately, the first mbsync was incomplete as it was missing about
+Unfortunately, the first `mbsync` was incomplete as it was missing about
 15,000 mails:
 
     anarcat@angela:~(main)$ find Maildir -type f -type f -a \! -name '.*' | wc -l 
@@ -126,7 +126,7 @@ with:
       printf "%s\t%d\n" $folder $(find "$folder" -type f -a \! -name '.*' | wc -l );
     done
 
-The special `\! -name '.*'` bit is to ignore the mbsync metadata,
+The special `\! -name '.*'` bit is to ignore the `mbsync` metadata,
 which creates `.uidvalidity` and `.mbsyncstate` in every folder. That
 ignores about 200 files but since they are spread around all folders,
 which was making it impossible to review where the problem was.
@@ -347,7 +347,7 @@ What remains is:
     21
     anarcat@angela:~(main)$ 
 
-ie. 21 missing from mbsync, and, surprisingly, 2 missing from the
+ie. 21 missing from `mbsync`, and, surprisingly, 2 missing from the
 original mail spool.
 
 Further inspection also showed they were *all* messages with some sort

some more edits
diff --git a/blog/2021-11-21-mbsync-vs-offlineimap.md b/blog/2021-11-21-mbsync-vs-offlineimap.md
index 778ed99a..c8da7ec1 100644
--- a/blog/2021-11-21-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-21-mbsync-vs-offlineimap.md
@@ -159,7 +159,7 @@ because it's global.
 Using a more standard format like .INI or TOML would improve things
 greatly here.
 
-## stellar performance
+## Stellar performance
 
 The full sync of my 300,000+ messages (12GB) took 56 minutes and 6
 seconds, which is impressive.
@@ -233,7 +233,7 @@ TODO: multitime
 
 ## Great user interface
 
-Compared to offlineimap and (ahem) SMD, the mbsync UI is kind of neat:
+Compared to OfflineIMAP and (ahem) SMD, the mbsync UI is kind of neat:
 
     anarcat@angela:~(main)$ mbsync -a
     Notice: Master/Slave are deprecated; use Far/Near instead.
@@ -602,7 +602,7 @@ corruption on mailboxes was fixed:
         notmuch new
         pv notmuch.dump | notmuch restore
 
-# offlineimap
+# OfflineIMAP
 
 I've used [OfflineIMAP](https://github.com/OfflineIMAP/offlineimap3) for a long time before switching to SMD. I
 don't exactly remember why I started using it, but I do remember it
@@ -616,7 +616,7 @@ set. Thankfully, a new team of volunteers ported OfflineIMAP to Python
 3 and we can now test that new version to see if it is an improvement
 over mbsync.
 
-## crash on full sync
+## Crash on full sync
 
 The first thing we notice when doing a full sync is this crash:
 
@@ -764,6 +764,8 @@ lovely `0.0~git20210225.1e7ef9e+dfsg-4`), while the current `sid`
 version (the equally gorgeous `0.0~git20211018.e64c254+dfsg-1`) seems
 unaffected.
 
+## Tolerable performance
+
 The new release still crashes, except it does so at the very end,
 which is an improvement, I guess, since the mails do get transferred:
 
@@ -811,7 +813,8 @@ Command exited with non-zero status 1
 This is 8h31m for transferring 12G, which is around 3.1Mbit/s. That is
 *nine* times slower than mbsync, almost an order of magnitude!
 
-Incrementals are also much slower:
+Now that we have a full sync, we can test incremental
+synchronization. That is also much slower:
 
     ===> multitime results
     1: sh -c "offlineimap -o || true"
@@ -820,11 +823,13 @@ Incrementals are also much slower:
     user        23.912      0.473       23.404      23.795      24.947      
     sys         1.743       0.105       1.607       1.729       2.002
 
-That is also an order of magnitude slower than mbsync, and
+That is also an order of magnitude slower than `mbsync`, and
 significantly slower than what you'd expect from a sync process. ~30
 seconds is long enough to make me impatient and distracted; 3 seconds,
 less so: I can wait and see the results almost immediately.
 
+## Integrity check
+
 That said: this is still on a gigabit link. It's technically
 *possible* that OfflineIMAP performs better than `mbsync` over a slow
 link, but I Haven't tested that theory.

tweak conclusion
diff --git a/blog/2021-11-21-one-last-smd-crash.md b/blog/2021-11-21-one-last-smd-crash.md
index 6b63c878..e09eff2e 100644
--- a/blog/2021-11-21-one-last-smd-crash.md
+++ b/blog/2021-11-21-one-last-smd-crash.md
@@ -7,7 +7,9 @@ me one too many times
 to an alternative mail synchronization tool, I looked into using my
 IMAP server again, and found out my mail spool was in a pretty bad
 shape. I'm [[comparing mbsync and offlineimap in the next
-post|2021-11-21-mbsync-vs-offlineimap]].
+post|2021-11-21-mbsync-vs-offlineimap]] but this post talks about how
+I recovered the mail spool so that tools like those could correctly
+synchronise the mail spool again.
 
 [[!toc levels=3]]
 
@@ -361,7 +363,7 @@ SMD has stellar performance, but this comes at a huge cost: it
 accesses the mail storage directly. This can (and has) created
 *significant* problems on the mail server. It's unclear exactly *why*
 those things happen, but Dovecot expects a particular storage format
-on its file, and it seems unwise to bypass that. 
+on its file, and it seems unwise to bypass that.
 
 In the future, I'll try to remember to avoid that, especially since
 mechanisms like SMD require special server access (SSH) which, in the
@@ -375,12 +377,16 @@ could find, but it could have gone differently and it would have been
 possible for SMD to permanently corrupt significant part of my mail
 archives.
 
-I recommend SMD users start looking for alternatives. The project has
-been [archived upstream](https://github.com/gares/syncmaildir/), and the [Debian package has been
-orphaned](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=995531). I have seen significant mail box corruption, including
-[entire mail spool destruction](https://github.com/gares/syncmaildir/issues/18), mostly due to [incorrect locking
-code](https://github.com/gares/syncmaildir/blob/388f3ebd351b3cb046b7d3d9c0cce12acdf2e18c/smd-common#L444). I have filed a [release-critical bug in Debian](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1000322) to make
-sure it doesn't ship with Debian bookworm.
+In the end, however, the last drop was just another weird bug which,
+ironically, SMD mysteriously recovered from on its own while I was
+writing this documentation and migrating away from it.
+
+In any case, I recommend SMD users start looking for alternatives. The
+project has been [archived upstream](https://github.com/gares/syncmaildir/), and the [Debian package has
+been orphaned](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=995531). I have seen significant mail box corruption,
+including [entire mail spool destruction](https://github.com/gares/syncmaildir/issues/18), mostly due to [incorrect
+locking code](https://github.com/gares/syncmaildir/blob/388f3ebd351b3cb046b7d3d9c0cce12acdf2e18c/smd-common#L444). I have filed a [release-critical bug in Debian](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1000322)
+to make sure it doesn't ship with Debian bookworm.
 
 Alternatives like `mbsync` provide fast and reliable transport,
 including over SSH. See the [[next

publish second posts, add tags on the first
diff --git a/blog/2021-11-21-mbsync-vs-offlineimap.md b/blog/2021-11-21-mbsync-vs-offlineimap.md
index b8539a04..778ed99a 100644
--- a/blog/2021-11-21-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-21-mbsync-vs-offlineimap.md
@@ -890,4 +890,4 @@ Time will tell if I will stick with that setup. I'm certainly curious
 about the promises of interimap and mail-sync, but I have ran out of
 time on this project.
 
-[[!tag draft]]
+[[!tag debian-planet python-planet  email software syncmaildir sysadmin]]
diff --git a/blog/2021-11-21-one-last-smd-crash.md b/blog/2021-11-21-one-last-smd-crash.md
index 31055bf2..6b63c878 100644
--- a/blog/2021-11-21-one-last-smd-crash.md
+++ b/blog/2021-11-21-one-last-smd-crash.md
@@ -387,4 +387,4 @@ including over SSH. See the [[next
 article|2021-11-21-mbsync-vs-offlineimap]] for further discussion of
 the alternatives.
 
-[[!tag debian-planet python-planet ]]
+[[!tag debian-planet python-planet email fail syncmaildir sysadmin]]

update links to smd
diff --git a/blog/2021-11-21-mbsync-vs-offlineimap.md b/blog/2021-11-21-mbsync-vs-offlineimap.md
index 9ebe9996..b8539a04 100644
--- a/blog/2021-11-21-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-21-mbsync-vs-offlineimap.md
@@ -74,6 +74,14 @@ Interesting that `rsync` manages to almost beat a plain `tar` on file
 transfer, I'm actually surprised by how fast it performs here,
 considering there are many little files to transfer.
 
+Finally, note that when I migrated to SMD, I wrote a small
+[[performance
+comparison|services/mail/syncmaildir#performance-comparison]] that
+could be interesting here. It show SMD to be faster than OfflineIMAP,
+but not as much as we see here. In fact, it looks like OfflineIMAP
+slowed down significantly since I last did tests on it, but this could
+be due to my larger mail spool.
+
 # mbsync
 
 The [isync](https://isync.sourceforge.io/) (AKA `mbsync`) project is written in C and supports
diff --git a/services/mail.mdwn b/services/mail.mdwn
index 0abc6be9..e051bada 100644
--- a/services/mail.mdwn
+++ b/services/mail.mdwn
@@ -677,11 +677,15 @@ Delivery and retrieval over SSH
 ===============================
 
 I have switched from using IMAP and SMTP to receive and deliver email
-to SSH as a transport mechanism. This is possible thanks to two
-different bits of software, [syncmaildir][] to replace IMAP and I
-wrote [rsendmail][] to replace SMTP. The former is documented in
-[[services/mail/syncmaildir]] and the latter is documented in the
-upstream rsendmail documentation.
+to SSH as a transport mechanism. 
+
+This was originally implemented with [syncmaildir][] (SMD) to replace
+IMAP, but I have now [[switched to
+mbsync|blog/2021-11-21-mbsync-vs-offlineimap]]. I also wrote
+[rsendmail][] to replace SMTP.
+
+The my old SMD setup is documented in [[services/mail/syncmaildir]]
+and the latter is documented in the upstream rsendmail documentation.
 
 This makes it so I do not need to use clear-text passwords to deliver
 or retrieve email which means everything can be fully automated

finish editing second article
diff --git a/blog/2021-11-21-mbsync-vs-offlineimap.md b/blog/2021-11-21-mbsync-vs-offlineimap.md
index 964e8a65..9ebe9996 100644
--- a/blog/2021-11-21-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-21-mbsync-vs-offlineimap.md
@@ -4,12 +4,8 @@ After recovering from my [[latest email
 crash|blog/2021-11-21-one-last-smd-crash]]
 ([[previously|blog/2021-06-29-another-mail-crash]],
 [[previously|blog/2021-03-22-email-crash/]]), I had to figure out
-which tool I should be using. I had many options (mostly detailed in
-the [[second mail crash
-documentation|blog/2021-06-29-another-mail-crash]]), but I figured I
-would start with a popular one (`mbsync`) partly because it would
-allow me to keep my current "password-less" setup by using an SSH
-tunnel.
+which tool I should be using. I had many options but I figured I would
+start with a popular one (`mbsync`).
 
 But I also evaluated OfflineIMAP which was resurrected from the Python
 2 apocalypse, and because I had used it before, for a long time.
@@ -18,7 +14,7 @@ Read on for the details.
 
 [[!toc levels=2]]
 
-# Benchmarking setup
+# Benchmark setup
 
 All programs were tested against a Dovecot 1:2.3.13+dfsg1-2 server,
 running Debian bullseye. 
@@ -27,10 +23,11 @@ The [[client|hardware/angela]] is a Purism 13v4 laptop with a Samsung
 SSD 970 EVO 1TB NVMe drive. 
 
 The [[server|hardware/server/marcos/]] is a custom build with a AMD
-Ryzen 5 2600 CPU, with a RAID-1 array made of two NVMe drives (Intel
+Ryzen 5 2600 CPU, and a RAID-1 array made of two NVMe drives (Intel
 SSDPEKNW010T8 and WDC WDS100T2B0C).
 
-The mail spool I am testing against has almost 400k messages and 13GB:
+The mail spool I am testing against has almost 400k messages and takes
+13GB of disk space:
 
     $ notmuch count --exclude=false
     372758
@@ -38,11 +35,15 @@ The mail spool I am testing against has almost 400k messages and 13GB:
     13G	Maildir
 
 The baseline we are comparing against is SMD ([syncmaildir](https://github.com/gares/syncmaildir)) which
-performs the sync in about 7-8 seconds (3.5 seconds for each push/pull
-command). Anything close to that or better is good enough. I do not
-have recent numbers for a SMD full sync baseline, but the [[setup
+performs the sync in about 7-8 seconds locally (3.5 seconds for each
+push/pull command) and about 10-12 seconds remotely.
+
+Anything close to that or better is good enough. I do not have recent
+numbers for a SMD full sync baseline, but the [[setup
 documentation|services/mail/syncmaildir/#full-synchronization]]
-mentions 20 minutes for a full sync.
+mentions 20 minutes for a full sync. That was a few years ago, and the
+spool has obviously grown since then, so that is not a reliable
+baseline.
 
 A baseline for a full sync might be also set with rsync, which copies
 files at nearly 40MB/s, or 317Mb/s!
@@ -210,6 +211,18 @@ considering the double-connect cost:
     user        0.718       0.037       0.679       0.711       0.793       
     sys         0.322       0.024       0.284       0.320       0.365
 
+Those tests were all done on a Gigabit link, but what happens on a
+slower link? My server uplink is surprisingly slow: 25/6 Mbps. There
+`mbsync` doesn't far as well, and is worse than the SMD baseline:
+
+    1.80user 0.54system 0:35.70elapsed 6%CPU (0avgtext+0avgdata 25984maxresident)k
+    0inputs+0outputs (0major+19315minor)pagefaults 0swaps
+
+That's 35 seconds for a sync, which is an order of magnitude slower
+than SMD.
+
+TODO: multitime
+
 ## Great user interface
 
 Compared to offlineimap and (ahem) SMD, the mbsync UI is kind of neat:
@@ -218,7 +231,7 @@ Compared to offlineimap and (ahem) SMD, the mbsync UI is kind of neat:
     Notice: Master/Slave are deprecated; use Far/Near instead.
     C: 1/2  B: 204/205  F: +0/0 *0/0 #0/0  N: +1/2 *0/0 #0/0
 
-(Note that nice switch away from slavery too.)
+(Note that nice [switch away from slavery](https://github.com/get-woke/woke) too.)
 
 The display is minimalist, and yet informative. It's not obvious from
 the start what it does, but the manpage is instructive at least on
@@ -242,22 +255,23 @@ In other words:
    * `*0/0`: no flag changed
    * `#0/0`: no message deleted
 
-I like it, but I'm not sure how it's going to translate into useful
-information in a systemd service.
+I like it. It does not, unfortunately, show up when you run it in
+systemd, which is a bit annoying as I like to see mail traffic in the
+logs.
 
 ## Interoperability issue
 
-In my notmuch setup, I have bound key `S` to "mark spam", which
-basically assigns the tag `spam` to the message and removes a bunch of
-others. Then I have a [notmuch-purge](https://gitlab.com/anarcat/scripts/-/blob/main/notmuch-purge) script which moves that
-message to the spam folder, for training purposes. It basically does
-this:
+In my [[notmuch setup|blog/2016-05-12-email-setup]], I have bound key
+`S` to "mark spam", which basically assigns the tag `spam` to the
+message and removes a bunch of others. Then I have a
+[notmuch-purge](https://gitlab.com/anarcat/scripts/-/blob/main/notmuch-purge) script which moves that message to the spam folder,
+for training purposes. It basically does this:
 
     notmuch search --output=files --format=text0 "$search_spam" \
         | xargs -r -0 mv -t "$HOME/Maildir/${PREFIX}junk/cur/"
 
-This method, which worked fine in SMD (and possibly also OfflineIMAP)
-created this error on sync:
+This method, which worked fine in SMD (and also OfflineIMAP) created
+this error on sync:
 
     Maildir error: duplicate UID 37578.
 
@@ -278,9 +292,9 @@ This is actually a known limitation or, as [mbsync(1)](manpages.debian.org/mbsyn
 >     (setq mu4e-change-filenames-when-moving t)
 
 So it seems I would need to fix my script. It's unclear *how* the
-paths should be renamed, that said, which is unfortunate, because I
-would need to change my script to adapt to `mbsync`, but I can't tell
-how.
+paths should be renamed, which is unfortunate, because I would need to
+change my script to adapt to `mbsync`, but I can't tell how just from
+reading the above.
 
 Fortunately, someone else already fixed that issue: [afew](https://afew.readthedocs.io/), a
 notmuch tagging script (much puns, such hurt), has a [move mode](https://afew.readthedocs.io/en/latest/move_mode.html)
@@ -288,17 +302,17 @@ that can [rename files](https://afew.readthedocs.io/en/latest/move_mode.html#ren
 with mbsync. I had already been told about afew, but it's one more
 reason to standardize my notmuch hooks on that project, it looks like.
 
-A manual fix is to rename the file to remove the `U=` field: `mbsync`
-will generate a new one and then sync correctly.
+(A manual fix is actually to rename the file to remove the `U=` field:
+`mbsync` will generate a new one and then sync correctly.)
 
 ## Stability issues
 
-The newer release in Debian bookworm (currently at 1.4.3) has major
+The newer release in Debian bookworm (currently at 1.4.3) has
 stability issues on full sync. I filed [bug 999804](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=999804) in Debian about
-this, which lead to a [long thread on the upstream mailing list](https://sourceforge.net/p/isync/mailman/isync-devel/thread/87a6i1fo5y.fsf%40angela.anarc.at/). I
-have found at least three distinct crashes that could be double-free
-bugs "[which might be exploitable in the worst case](https://sourceforge.net/p/isync/mailman/message/37385942/)", not a
-reassuring prospect.
+this, which lead to a [thread on the upstream mailing list](https://sourceforge.net/p/isync/mailman/isync-devel/thread/87a6i1fo5y.fsf%40angela.anarc.at/). I have
+found at least three distinct crashes that could be double-free bugs
+"[which might be exploitable in the worst case](https://sourceforge.net/p/isync/mailman/message/37385942/)", not a reassuring
+prospect.
 
 The thing is: mbsync is really fast, but the downside of that is that
 it's written in C, and with that comes a whole set of security
@@ -308,7 +322,9 @@ isync, but the above issues show there could be many more.
 Reading the source code certainly did not make me very comfortable
 with trusting it with arbitrary data. I have considered sandboxing it
 with systemd (below) but having systemd run as a `--user` process
-makes that difficult.
+makes that difficult. I have also considered using an [apparmor
+profile](https://github.com/krathalan/apparmor-profiles/blob/master/profiles/mbsync) but that is not trivial because we need to allow SSH and
+only some parts of it...
 
 Thankfully, upstream has been diligent at addressing the issues I have
 found providing a patch within a few days which did fix the sync
@@ -327,14 +343,17 @@ I have used the following `.service` file:
     ConditionHost=!marcos
     Wants=network-online.target
     After=network-online.target
+    Before=notmuch-new.service
 
     [Service]
     Type=oneshot
     ExecStart=/usr/bin/mbsync -a
+    Nice=10
+    IOSchedulingClass=idle
+    NoNewPrivileges=true
 
     [Install]
     WantedBy=default.target
-    Wants=notmuch-new.service
 
 And the following `.timer`:
 
@@ -356,7 +375,7 @@ time of writing:
 
     [Unit]
     Description=notmuch new
-    After=smd-pull.service smd-push.service
+    After=mbsync.service
 
     [Service]
     Type=oneshot

(Diff truncated)
link to the next crash
diff --git a/blog/2021-06-29-another-mail-crash.md b/blog/2021-06-29-another-mail-crash.md
index ab889628..1e6f7b43 100644
--- a/blog/2021-06-29-another-mail-crash.md
+++ b/blog/2021-06-29-another-mail-crash.md
@@ -158,6 +158,9 @@ mechanisms. I do not remember ever losing that much mail before. At
 worst, offlineimap would duplicate emails like mad, but never destroy
 my entire mail spool that way.
 
+Update: I *have* migrated to another tool after one more failure from
+SMD, see the [[crash log and recovery|2021-11-21-one-last-smd-crash]].
+
 As [[mentioned
 before|blog/2021-03-22-email-crash/#workarounds-and-solutions]], there
 are other programs that sync mail. See [[the mbsync vs OfflineIMAP

finish editing first article
diff --git a/blog/2021-11-21-one-last-smd-crash.md b/blog/2021-11-21-one-last-smd-crash.md
index d848eeda..31055bf2 100644
--- a/blog/2021-11-21-one-last-smd-crash.md
+++ b/blog/2021-11-21-one-last-smd-crash.md
@@ -7,7 +7,7 @@ me one too many times
 to an alternative mail synchronization tool, I looked into using my
 IMAP server again, and found out my mail spool was in a pretty bad
 shape. I'm [[comparing mbsync and offlineimap in the next
-post|2021-11-21-mbsync-vs-offlineimap]]
+post|2021-11-21-mbsync-vs-offlineimap]].
 
 [[!toc levels=3]]
 
@@ -35,12 +35,11 @@ On Monday, SMD just started failing with this error:
     nov 15 16:16:17 angela systemd[2305]: smd-pull.service: Failed with result 'exit-code'.
     nov 15 16:16:17 angela systemd[2305]: Failed to start pull emails with syncmaildir.
 
-What is frustrating here is that there's actually no network error
-here. Everything was working fine and then one minute to the next it
-starts failing. Running the command by hand I did see a different
-message, but now I have lost it in my backlog. It had something to do
-with a filename being too long, and I gave up debugging after a
-while. 
+What is frustrating is that there's actually no network error
+here. Running the command by hand I did see a different message, but
+now I have lost it in my backlog. It had something to do with a
+filename being too long, and I gave up debugging after a while. This
+happened suddenly too, which added to the confusion.
 
 In a fit of rage I started this blog post and experimenting with
 alternatives, which led me down a lot of rabbit holes.
@@ -49,13 +48,16 @@ Reviewing my [[previous mail crash
 documentation|blog/2021-06-29-another-mail-crash]], it seems most
 solution involve talking to an IMAP server, so I figured I would just
 do that. Wanting to try something new, i gave [isync](https://isync.sourceforge.io/) (AKA
-`mbsync`) a try.
+`mbsync`) a try. Oh dear, I did not expect how much trouble just
+talking to my IMAP server would be. It's not isync's fault, for what
+it's worth, but it's the primary tool I used to debug things, and
+served me well in that regard.
 
 # mailbox corruption
 
-The first thing I found out is that my IMAP spool was basically
-corrupted. `mbsync` would stop on a `FETCH` command and Dovecot would
-give me those errors on the server side:
+The first thing I found out is that certain messages in the IMAP spool
+were corrupted. `mbsync` would stop on a `FETCH` command and Dovecot
+would give me those errors on the server side:
 
     nov 16 15:31:27 marcos dovecot[3621800]: imap(anarcat)<3630489><wAmSzO3QZtfAqAB1>: Error: Mailbox junk: Maildir filename has wrong W value, renamed the file from /home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495,W=2578:2,S to /home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495:2,S
     nov 16 15:31:27 marcos dovecot[3621800]: imap(anarcat)<3630489><wAmSzO3QZtfAqAB1>: Error: Mailbox junk: Deleting corrupted cache record uid=1582: UID 1582: Broken virtual size in mailbox junk: read(/home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495,W=2578:2,S): FETCH BODY[] got too little data: 2540 vs 2578
@@ -67,6 +69,8 @@ and:
     nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: UID=19288: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288) (read reason=)
     nov 16 13:53:08 marcos dovecot[3520770]: imap-login: Panic: epoll_ctl(del, 7) failed: Bad file descriptor
 
+## "wrong W value"
+
 At least the first error was automatically healed by Dovecot (by
 renaming the file without the `W=` flag). The problem is that the
 `FETCH` command fails and `mbsync` exits noisily. So you need to
@@ -74,12 +78,18 @@ constantly restart `mbsync` with a silly command like:
 
     while ! mbsync -a; do sleep 1; done
 
+## "cached message size larger than expected"
+
 The second problem is much harder to fix, because dovecot does *not*
 recover automatically. The above loop was taking too long: one full
-IMAP roundtrip (with authentication) for every corrupt message... So I
-read a lot on the [Dovecot documentation on the maildir format](https://doc.dovecot.org/admin_manual/mailbox_formats/maildir/),
-and wrote an extensive [fix script](https://gitlab.com/anarcat/scripts/-/blob/main/dovecot-fix-size-cache.py) for those two errors. The
-script worked and mbsync was able to sync the entire mail spool.
+IMAP roundtrip (with authentication) for every corrupt message...
+
+## Workaround
+
+So I read a lot on the [Dovecot documentation on the maildir
+format](https://doc.dovecot.org/admin_manual/mailbox_formats/maildir/), and wrote an extensive [fix script](https://gitlab.com/anarcat/scripts/-/blob/main/dovecot-fix-size-cache.py) for those two
+errors. The script worked and mbsync was able to sync the entire mail
+spool.
 
 And no, [rebuilding the index files](https://dovecot.org/pipermail/dovecot/2019-June/116227.html) didn't work. Also tried
 `doveadm force-resync -u anarcat` which didn't do anything.
@@ -90,10 +100,11 @@ also stored elsewhere.
     service dovecot stop ; find -name 'dovecot*' -delete; service dovecot start
 
 This would have totally broken any existing clients, but thankfully
-I'm starting from scratch (except maybe webmail, but that's easy to
-recover from).
+I'm starting from scratch (except maybe webmail, but I'm hoping it
+will self-heal as well, assuming it only has a cache and not a full
+replica of the mail spool).
 
-# Incoherence between maildir and IMAP
+# Incoherence between Maildir and IMAP
 
 Unfortunately, the first mbsync was incomplete as it was missing about
 15,000 mails:
@@ -103,8 +114,8 @@ Unfortunately, the first mbsync was incomplete as it was missing about
     anarcat@angela:~(main)$ find Maildir-mbsync/ -type f -a \! -name '.*' | wc -l 
     369221
 
-As it turns out, `mbsync` was not at fault here: this was yet more
-mail spool corruption.
+As it turns out, `mbsync` was not at fault here either: this was yet
+more mail spool corruption.
 
 It's actually 26 folders with different sizes, which can be found
 with:
@@ -114,9 +125,9 @@ with:
     done
 
 The special `\! -name '.*'` bit is to ignore the mbsync metadata,
-which leaves `.uidvalidity` and `.mbsyncstate` in every folder. That
+which creates `.uidvalidity` and `.mbsyncstate` in every folder. That
 ignores about 200 files but since they are spread around all folders,
-it was making it impossible to review where the problem was.
+which was making it impossible to review where the problem was.
 
 Here is what the diff looks like:
 
@@ -157,22 +168,24 @@ Here is what the diff looks like:
 ## Misfiled messages
 
 It's a bit all over the place, but we can already notice some huge
-diffs, for example in the `Archives` folders. As it turns out, at
-least 12,000 of those missing mails were actually misfiled: instead of
-being in the `Maildir/.Archives.2012/cur/` folder, they were
-*directly* in `Maildir/.Archives.2012/`. This is something that
-doesn't matter for SMD (~~and possibly for notmuch?~~ it does matter,
-notmuch suddenly found 12,000 new mails) but that definitely matters
-to Dovecot and therefore `mbsync`... After moving those files around,
-we get to a much more reasonable:
+differences between mailboxes, for example in the `Archives`
+folders. As it turns out, at least 12,000 of those missing mails were
+actually misfiled: instead of being in the
+`Maildir/.Archives.2012/cur/` folder, they were *directly* in
+`Maildir/.Archives.2012/`. This is something that doesn't matter for
+SMD (~~and possibly for notmuch?~~ it does matter, notmuch suddenly
+found 12,000 new mails) but that definitely matters to Dovecot and
+therefore `mbsync`...
+
+After moving those files around, we still have 4,000 message missing:
 
     anarcat@angela:~(main)$ find Maildir-mbsync/  -type f -a \! -name '.*' | wc -l 
     381196
     anarcat@angela:~(main)$ find Maildir/  -type f -a \! -name '.*' | wc -l 
     385053
 
-The problem is that *those* 4,000 missing mails are much harder to
-track. Take, for example, `.Archives.2011`: it's a single file
+The problem is that *those* 4,000 missing mails are harder to
+track. Take, for example, `.Archives.2011`, which has a single messge
 missing, out of 3,582. And the files are not identical: the checksums
 don't match after going through the IMAP transport, so we can't use a
 tool like [hashdeep](http://md5deep.sourceforge.net/) to compare the trees and find why that one
@@ -184,24 +197,56 @@ One big chunk of the 4,000, however, is a special folder called
 `register` in my spool, which I was syncing separately (see [Securing
 registration email](https://anarc.at/blog/2019-03-20-locking-down-registration-mail/) for details on that setup). That actually
 covers 3,700 of those messages, so I actually have a more modest 300
-messages to figure out.
+messages to figure out, after (easily!) configuring `mbsync` to sync
+that folder separately:
+
+     @@ -30,9 +33,29 @@ Slave :anarcat-local:
+      # Exclude everything under the internal [Gmail] folder, except the interesting folders
+      #Patterns * ![Gmail]* "[Gmail]/Sent Mail" "[Gmail]/Starred" "[Gmail]/All Mail"
+      # Or include everything
+     -Patterns *
+     +#Patterns *
+     +Patterns * !register  !.register
+      # Automatically create missing mailboxes, both locally and on the server
+      #Create Both
+      Create slave
+      # Sync the movement of messages between folders and deletions, add after making sure the sync works
+      #Expunge Both
+     +
+     +IMAPAccount anarcat-register
+     +Host imap.anarc.at
+     +User register
+     +PassCmd "pass imap.anarc.at-register"
+     +SSLType IMAPS
+     +CertificateFile /etc/ssl/certs/ca-certificates.crt
+     +
+     +IMAPStore anarcat-register-remote
+     +Account anarcat-register
+     +
+     +MaildirStore anarcat-register-local
+     +SubFolders Maildir++
+     +Inbox ~/Maildir-mbsync/.register/
+     +
+     +Channel anarcat-register
+     +Master :anarcat-register-remote:
+     +Slave :anarcat-register-local:
+     +Create slave
 
 ## "tmp" folders and empty messages
 
 After syncing the "register" messages, I end up with the measly

(Diff truncated)
rename to today
diff --git a/blog/2021-06-29-another-mail-crash.md b/blog/2021-06-29-another-mail-crash.md
index 4e1dfb95..ab889628 100644
--- a/blog/2021-06-29-another-mail-crash.md
+++ b/blog/2021-06-29-another-mail-crash.md
@@ -161,6 +161,6 @@ my entire mail spool that way.
 As [[mentioned
 before|blog/2021-03-22-email-crash/#workarounds-and-solutions]], there
 are other programs that sync mail. See [[the mbsync vs OfflineIMAP
-review|2021-11-18-mbsync-vs-offlineimap]] the list of alternatives.
+review|2021-11-21-mbsync-vs-offlineimap]] the list of alternatives.
 
 [[!tag syncmaildir rsendmail email fail sysadmin debian-planet python-planet]]
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-21-mbsync-vs-offlineimap.md
similarity index 99%
rename from blog/2021-11-18-mbsync-vs-offlineimap.md
rename to blog/2021-11-21-mbsync-vs-offlineimap.md
index ff377666..964e8a65 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-21-mbsync-vs-offlineimap.md
@@ -1,7 +1,7 @@
 [[!meta title="mbsync vs OfflineIMAP"]]
 
 After recovering from my [[latest email
-crash|blog/2021-11-18-one-last-smd-crash]]
+crash|blog/2021-11-21-one-last-smd-crash]]
 ([[previously|blog/2021-06-29-another-mail-crash]],
 [[previously|blog/2021-03-22-email-crash/]]), I had to figure out
 which tool I should be using. I had many options (mostly detailed in
@@ -523,7 +523,7 @@ lost messages:
     Warning: cannot apply tags to missing message: notmuch-sha1-0747b020f7551415b9bf5059c58e0a637ba53b13
     [...]
 
-As detailed in [[the crash report|2021-11-18-one-last-smd-crash]],
+As detailed in [[the crash report|2021-11-21-one-last-smd-crash]],
 all of those were actually innocuous and could be ignored.
 
 ## New workstation setup
diff --git a/blog/2021-11-18-one-last-smd-crash.md b/blog/2021-11-21-one-last-smd-crash.md
similarity index 97%
rename from blog/2021-11-18-one-last-smd-crash.md
rename to blog/2021-11-21-one-last-smd-crash.md
index ac915d24..d848eeda 100644
--- a/blog/2021-11-18-one-last-smd-crash.md
+++ b/blog/2021-11-21-one-last-smd-crash.md
@@ -1,11 +1,13 @@
-[[!meta title="One last syncmaildir crash"]]
+[[!meta title="The last syncmaildir crash"]]
 
-My [syncmaildir](https://github.com/gares/syncmaildir) (SMD)
-[[setup|services/mail/syncmaildir/]] failed me one too many
-times ([[previously|blog/2021-06-29-another-mail-crash]],
+My [syncmaildir](https://github.com/gares/syncmaildir) (SMD) [[setup|services/mail/syncmaildir/]] failed
+me one too many times
+([[previously|blog/2021-06-29-another-mail-crash]],
 [[previously|blog/2021-03-22-email-crash/]]). In an attempt to migrate
-to an alternative tool to sync my mail, I looked into using my IMAP
-server again, and found out my mail spool was in a pretty bad shape.
+to an alternative mail synchronization tool, I looked into using my
+IMAP server again, and found out my mail spool was in a pretty bad
+shape. I'm [[comparing mbsync and offlineimap in the next
+post|2021-11-21-mbsync-vs-offlineimap]]
 
 [[!toc levels=3]]
 

what i did to deploy on curie
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index 53cd721e..ff377666 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -526,6 +526,68 @@ lost messages:
 As detailed in [[the crash report|2021-11-18-one-last-smd-crash]],
 all of those were actually innocuous and could be ignored.
 
+## New workstation setup
+
+This is not exactly clearly documented, but this should basically be
+it:
+
+ 1. install isync, with the patch:
+ 
+        dpkg -i isync_1.4.3-1.1~_amd64.deb
+
+ 2. copy all files over:
+ 
+        rsync -a --info=progress2 angela:Maildir/ Maildir-mbsync/
+
+ 4. backup the notmuch directory
+ 
+        notmuch dump | pv > notmuch.dump
+
+ 5. trash the notmuch database:
+ 
+        rm -rf Maildir-mbsync/.notmuch/xapian/
+
+ 3. move old files aside, if present
+ 
+        mv Maildir Maildir-smd
+
+ 6. move new files in place:
+ 
+        mv Maildir-mbsync Maildir
+
+ 7. rename all files:
+ 
+        find Maildir/ -type f -name '*.angela,*' -print0 |  rename -0 's/\.angela,/\.curie,/'
+
+ 8. create the SSH key:
+
+        ssh-keygen -t ed25519 -f .ssh/id_ed25519_mbsync
+        cat .ssh/id_ed25519_mbsync.pub
+
+ 9. add to `.ssh/authorized_keys` on the server, like this:
+ 
+        command="/usr/lib/dovecot/imap",restrict ssh-ed25519 AAAAC...
+
+ 8. run a test sync, with `Create slave`, no `Expunge` or `Remove
+    statements`:
+    
+        mbsync register
+
+ 9. if that works well, try with all mailboxes:
+ 
+        mbsync -a
+
+ 10. if that works well, enable `Create both`, `Expunge both` and
+     `Remove both`, and try again:
+
+        mbsync register
+        mbsync -a
+
+ 11. reindex the notmuch database
+ 
+        notmuch new
+        pv notmuch.dump | notmuch restore
+
 # offlineimap
 
 I've used [OfflineIMAP](https://github.com/OfflineIMAP/offlineimap3) for a long time before switching to SMD. I

interoperability issue
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index c170647b..53cd721e 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -245,6 +245,51 @@ In other words:
 I like it, but I'm not sure how it's going to translate into useful
 information in a systemd service.
 
+## Interoperability issue
+
+In my notmuch setup, I have bound key `S` to "mark spam", which
+basically assigns the tag `spam` to the message and removes a bunch of
+others. Then I have a [notmuch-purge](https://gitlab.com/anarcat/scripts/-/blob/main/notmuch-purge) script which moves that
+message to the spam folder, for training purposes. It basically does
+this:
+
+    notmuch search --output=files --format=text0 "$search_spam" \
+        | xargs -r -0 mv -t "$HOME/Maildir/${PREFIX}junk/cur/"
+
+This method, which worked fine in SMD (and possibly also OfflineIMAP)
+created this error on sync:
+
+    Maildir error: duplicate UID 37578.
+
+And indeed, there are now two messages with that UID in the mailbox:
+
+    anarcat@angela:~(main)$ find Maildir/.junk/ -name '*U=37578*'
+    Maildir/.junk/cur/1637427889.134334_2.angela,U=37578:2,S
+    Maildir/.junk/cur/1637348602.2492889_221804.angela,U=37578:2,S
+
+This is actually a known limitation or, as [mbsync(1)](manpages.debian.org/mbsync) calls it, a
+"[RECOMMENDATION](https://manpages.debian.org/bullseye/isync/mbsync.1.en.html#RECOMMENDATIONS)":
+
+> When using the more efficient default UID mapping scheme, it is
+> important that the MUA renames files when moving them between
+> Maildir fold ers.  Mutt always does that, while mu4e needs to be
+> configured to do it:
+>
+>     (setq mu4e-change-filenames-when-moving t)
+
+So it seems I would need to fix my script. It's unclear *how* the
+paths should be renamed, that said, which is unfortunate, because I
+would need to change my script to adapt to `mbsync`, but I can't tell
+how.
+
+Fortunately, someone else already fixed that issue: [afew](https://afew.readthedocs.io/), a
+notmuch tagging script (much puns, such hurt), has a [move mode](https://afew.readthedocs.io/en/latest/move_mode.html)
+that can [rename files](https://afew.readthedocs.io/en/latest/move_mode.html#rename) correctly, specifically designed to deal
+with mbsync. I had already been told about afew, but it's one more
+reason to standardize my notmuch hooks on that project, it looks like.
+
+A manual fix is to rename the file to remove the `U=` field: `mbsync`
+will generate a new one and then sync correctly.
 
 ## Stability issues
 

finish tests, just need to do some editing and narration now
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index dd8ee9d7..c170647b 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -37,11 +37,41 @@ The mail spool I am testing against has almost 400k messages and 13GB:
     $ du -sh --exclude xapian Maildir
     13G	Maildir
 
-The baseline we are comparing against is SMD (syncmaildir) which
+The baseline we are comparing against is SMD ([syncmaildir](https://github.com/gares/syncmaildir)) which
 performs the sync in about 7-8 seconds (3.5 seconds for each push/pull
-command). Anything close to that or better is good enough.
+command). Anything close to that or better is good enough. I do not
+have recent numbers for a SMD full sync baseline, but the [[setup
+documentation|services/mail/syncmaildir/#full-synchronization]]
+mentions 20 minutes for a full sync.
 
-TODO: calculate a "baseline rate" based on rsync then tar performance.
+A baseline for a full sync might be also set with rsync, which copies
+files at nearly 40MB/s, or 317Mb/s!
+
+    anarcat@angela:tmp(main)$ time rsync -a --info=progress2 --exclude xapian  shell.anarc.at:Maildir/ Maildir/
+     12,647,814,731 100%   37.85MB/s    0:05:18 (xfr#394981, to-chk=0/395815)    
+    72.38user 106.10system 5:19.59elapsed 55%CPU (0avgtext+0avgdata 15988maxresident)k
+    8816inputs+26305112outputs (0major+50953minor)pagefaults 0swaps
+
+That is 5 minutes to transfer the entire spool. Incremental syncs are
+obviously pretty fast too:
+
+    anarcat@angela:tmp(main)$ time rsync -a --info=progress2 --exclude xapian  shell.anarc.at:Maildir/ Maildir/
+                  0   0%    0.00kB/s    0:00:00 (xfr#0, to-chk=0/395815)    
+    1.42user 0.81system 0:03.31elapsed 67%CPU (0avgtext+0avgdata 14100maxresident)k
+    120inputs+0outputs (3major+12709minor)pagefaults 0swaps
+
+As an extra curiosity, here's the performance with `tar`, pretty
+similar with `rsync`, minus incremental which I cannot be bothered to
+figure out right now:
+
+    anarcat@angela:tmp(main)$ time ssh shell.anarc.at tar --exclude xapian -cf - Maildir/ | pv -s 13G | tar xf - 
+    56.68user 58.86system 5:17.08elapsed 36%CPU (0avgtext+0avgdata 8764maxresident)k
+    0inputs+0outputs (0major+7266minor)pagefaults 0swaps
+    12,1GiO 0:05:17 [39,0MiB/s] [===================================================================> ] 92%
+
+Interesting that `rsync` manages to almost beat a plain `tar` on file
+transfer, I'm actually surprised by how fast it performs here,
+considering there are many little files to transfer.
 
 # mbsync
 
@@ -237,10 +267,7 @@ makes that difficult.
 
 Thankfully, upstream has been diligent at addressing the issues I have
 found providing a patch within a few days which did fix the sync
-issues.
-
-TODO: perform one more full sync to see if the patch actually fixes
-everything.
+issues, including on a full sync from scratch.
 
 ## Automation with systemd
 
diff --git a/blog/2021-11-18-one-last-smd-crash.md b/blog/2021-11-18-one-last-smd-crash.md
index f26eee2f..ac915d24 100644
--- a/blog/2021-11-18-one-last-smd-crash.md
+++ b/blog/2021-11-18-one-last-smd-crash.md
@@ -1,7 +1,7 @@
 [[!meta title="One last syncmaildir crash"]]
 
 My [syncmaildir](https://github.com/gares/syncmaildir) (SMD)
-[[setup|https://github.com/gares/syncmaildir]] failed me one too many
+[[setup|services/mail/syncmaildir/]] failed me one too many
 times ([[previously|blog/2021-06-29-another-mail-crash]],
 [[previously|blog/2021-03-22-email-crash/]]). In an attempt to migrate
 to an alternative tool to sync my mail, I looked into using my IMAP
@@ -314,8 +314,6 @@ place, and since they were mostly spam or administrative emails ("You
 have been unsubscribed from mailing list..."), it seems fairly
 harmless to ignore those.
 
-TODO: cleanup test account
-
 TODO: conclusion, tags, final edit.
 
 [[!tag draft]]

more todos
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index 1de5b8e8..dd8ee9d7 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -41,6 +41,8 @@ The baseline we are comparing against is SMD (syncmaildir) which
 performs the sync in about 7-8 seconds (3.5 seconds for each push/pull
 command). Anything close to that or better is good enough.
 
+TODO: calculate a "baseline rate" based on rsync then tar performance.
+
 # mbsync
 
 The [isync](https://isync.sourceforge.io/) (AKA `mbsync`) project is written in C and supports
@@ -452,8 +454,6 @@ lost messages:
 As detailed in [[the crash report|2021-11-18-one-last-smd-crash]],
 all of those were actually innocuous and could be ignored.
 
-TODO: garbage collect old Maildirs (offlineimap, smd)
-
 # offlineimap
 
 I've used [OfflineIMAP](https://github.com/OfflineIMAP/offlineimap3) for a long time before switching to SMD. I
@@ -733,4 +733,6 @@ Those are all the options I have considered, in alphabetical order
 
 Most projects were not evaluated due to lack of time.
 
+TODO: conclusion, tags, final edit.
+
 [[!tag draft]]
diff --git a/blog/2021-11-18-one-last-smd-crash.md b/blog/2021-11-18-one-last-smd-crash.md
index 745cdd07..f26eee2f 100644
--- a/blog/2021-11-18-one-last-smd-crash.md
+++ b/blog/2021-11-18-one-last-smd-crash.md
@@ -314,6 +314,8 @@ place, and since they were mostly spam or administrative emails ("You
 have been unsubscribed from mailing list..."), it seems fairly
 harmless to ignore those.
 
-TODO: conclusion.
+TODO: cleanup test account
+
+TODO: conclusion, tags, final edit.
 
 [[!tag draft]]

files compare fine, we've got integrity
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index e7116212..1de5b8e8 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -229,8 +229,16 @@ issues. The [Debian security tracker](https://security-tracker.debian.org) has o
 isync, but the above issues show there could be many more.
 
 Reading the source code certainly did not make me very comfortable
-with trusting it with arbitrary data. I will definitely consider
-sandboxing it as much as possible in systemd.
+with trusting it with arbitrary data. I have considered sandboxing it
+with systemd (below) but having systemd run as a `--user` process
+makes that difficult.
+
+Thankfully, upstream has been diligent at addressing the issues I have
+found providing a patch within a few days which did fix the sync
+issues.
+
+TODO: perform one more full sync to see if the patch actually fixes
+everything.
 
 ## Automation with systemd
 
@@ -426,369 +434,25 @@ Remove the `smd*` jobs from systemd and fix `notmuch-new.service`.
 During the migration, notmuch helpfully told me the full list of those
 lost messages:
 
-    Warning: cannot apply tags to missing message: notmuch-sha1-d0be3cf5f57defc75e6cbefaa0f468e7f8a2f49f
-    Warning: cannot apply tags to missing message: 20170923143147.BFEFC1A00AC@marcos.anarc.at
-    Warning: cannot apply tags to missing message: notmuch-sha1-2c9331b2fdde1bf2c7c8104fd6623712bd9dc19f
-    Warning: cannot apply tags to missing message: notmuch-sha1-4a21d84a7424640b53bab394f9d6819d0d482ae3
-    Warning: cannot apply tags to missing message: notmuch-sha1-ac6d0df1210717abf48c3c040ef2d922c408a294
-    Warning: cannot apply tags to missing message: notmuch-sha1-78c017379e7c2c350c545d3d9d7ffec241f9004e
-    Warning: cannot apply tags to missing message: notmuch-sha1-6537b24115699962b479b716778f9bebde4548aa
-    Warning: cannot apply tags to missing message: notmuch-sha1-a903e68fbeb8eec4c5cfd8aa74ea4f138db8a6b2
-    Warning: cannot apply tags to missing message: notmuch-sha1-f47de331cddef381a355c1e7a2b2b70478ba6b00
-    Warning: cannot apply tags to missing message: notmuch-sha1-ff9af4a8a7a03ff3b5d55a00728fe64be8b00eb6
-    Warning: cannot apply tags to missing message: notmuch-sha1-e4afd55ecb0c8dc026a1d37c514ce7d25e055b9c
-    Warning: cannot apply tags to missing message: notmuch-sha1-730c10bc421aa5e880c80459794333d42cd87372
-    Warning: cannot apply tags to missing message: notmuch-sha1-451b85cde55ae3e7dd0fd4258316008c301f1706
-    Warning: cannot apply tags to missing message: notmuch-sha1-793882a290834268e86c60941d9cd233af4d9755
-    Warning: cannot apply tags to missing message: notmuch-sha1-56a2874aec19b749745de3013ba52f86b91a0d01
-    Warning: cannot apply tags to missing message: notmuch-sha1-0eeb8f2779dbe40e20206b7aa95af3a434ded3e4
-    Warning: cannot apply tags to missing message: notmuch-sha1-a8f1f480e86e87c714e2f78732e308dc233cba9c
-    Warning: cannot apply tags to missing message: notmuch-sha1-e86d3afef3627f1c2b6769d20cbc946c070937f8
-    Warning: cannot apply tags to missing message: notmuch-sha1-e390fc067ef10fb401b63cc940bcbb164a1ee4bb
-    Warning: cannot apply tags to missing message: notmuch-sha1-a6d52472f2491dd87c7f044a8548f9025c6f16b5
-    Warning: cannot apply tags to missing message: 1117662302.429e2c5e5f380@67.18.121.132
-    Warning: cannot apply tags to missing message: 1117627371.429da3ebcf865@67.18.121.132
-    Warning: cannot apply tags to missing message: 1f2e235126095e5a5d4ef610669f11c0@openconcept.ca
-    Warning: cannot apply tags to missing message: a11a9cedaee1bbd816e1c0fb2b07ff63@openconcept.ca
-    Warning: cannot apply tags to missing message: 6ebc2221ca4c982f2d36ca3488fd4fc6@openconcept.ca
-    Warning: cannot apply tags to missing message: 00be01c57062$30838a00$b1165146@virginie807e5x
-    Warning: cannot apply tags to missing message: ece3ace394e2911a1cdcb9ab22bf6be5@openconcept.ca
-    Warning: cannot apply tags to missing message: 9f5e40b7bd8159842eeaf63eeadd7b21@openconcept.ca
-    Warning: cannot apply tags to missing message: 440BF6F8-6D75-11D9-9596-000D93343944@openconcept.ca
-    Warning: cannot apply tags to missing message: 7ff7dcd024a5a4c2472ab09a09c15a42@openconcept.ca
-    Warning: cannot apply tags to missing message: 00bd01c572c2$9690efb0$6401a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 2752b57076c1044362796aac295173d3@openconcept.ca
-    Warning: cannot apply tags to missing message: 5d1b07f0ac57e1588952c99feb53d770@openconcept.ca
-    Warning: cannot apply tags to missing message: efe05271c79f20e15b45d39cd99f0f97@openconcept.ca
-    Warning: cannot apply tags to missing message: 75CD2650-6A96-11D9-AEC6-000D93343944@openconcept.ca
-    Warning: cannot apply tags to missing message: 14a14ea4dffadfd71c71af508a739f8b@openconcept.ca
-    Warning: cannot apply tags to missing message: 007c01c5729e$78f55370$b1165146@virginie807e5x
-    Warning: cannot apply tags to missing message: 002d01c5065a$99d65130$6401a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: BAYC1-PASMTP02953B3192E37BB9FE2FADB88B0@CEZ.ICE
-    Warning: cannot apply tags to missing message: BDDD6AEA-566D-42C1-BE75-5B18828E4FD4@openconcept.ca
-    Warning: cannot apply tags to missing message: 20050216172343.GNNU1814.tomts9-srv.bellnexxia.net@mxmta.bellnexxia.net
-    Warning: cannot apply tags to missing message: 8382a6154cf79416c73f370cd574aaa8@openconcept.ca
-    Warning: cannot apply tags to missing message: c7db95f78233d5096ecc9f6b26f156da@openconcept.ca
-    Warning: cannot apply tags to missing message: 1117734753.429f4761e7f1a@67.18.121.132
-    Warning: cannot apply tags to missing message: 09ad34720a5658646c195bd9771306cc@openconcept.ca
-    Warning: cannot apply tags to missing message: 43582.200.169.20.98.1117717423.squirrel@www.koumbit.net
-    Warning: cannot apply tags to missing message: 006d01c51da6$c73a98d0$6401a8c0@Heather
-    Warning: cannot apply tags to missing message: b9240e32c34d4fd7c7849770efef86d6@openconcept.ca
-    Warning: cannot apply tags to missing message: 00a601c56084$26bf54b0$6401a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 17f296f546ac4d8236d49b9d632d7496@openconcept.ca
-    Warning: cannot apply tags to missing message: 0e8c83b49b94fe17cb10392c51fe9792@openconcept.ca
-    Warning: cannot apply tags to missing message: 6161b5ff70b86a78d743de4cde29e0e6@openconcept.ca
-    Warning: cannot apply tags to missing message: aa986ef2e1746e1d866b40f277c6e01a@openconcept.ca
+    [...]
+    Warning: cannot apply tags to missing message: CAN6gO7_QgCaiDFvpG3AXHi6fW12qaN286+2a7ERQ2CQtzjSEPw@mail.gmail.com
+    Warning: cannot apply tags to missing message: CAPTU9Wmp0yAmaxO+qo8CegzRQZhCP853TWQ_Ne-YF94MDUZ+Dw@mail.gmail.com
     Warning: cannot apply tags to missing message: F5086003-2917-4659-B7D2-66C62FCD4128@gmail.com
-    Warning: cannot apply tags to missing message: db803b0a46fbb724ecc864a70749e2eb@openconcept.ca
-    Warning: cannot apply tags to missing message: 1118397683.42a964f39c428@67.18.121.132
-    Warning: cannot apply tags to missing message: 1118175553.42a6014202765@67.18.121.132
-    Warning: cannot apply tags to missing message: 6819e6388394699d47285a6274ff3d03@openconcept.ca
-    Warning: cannot apply tags to missing message: 7D561B8C-F4A5-48AB-96E8-6AB888FB3952@gmail.com
-    Warning: cannot apply tags to missing message: 14a832ae6a1d9527b88630abe10eeb07@openconcept.ca
-    Warning: cannot apply tags to missing message: 16bc0ed6fa2798ce8fa0d26694d552a4@openconcept.ca
-    Warning: cannot apply tags to missing message: 1fca80b4c90c62faa3f05cb97e5f7fce@openconcept.ca
-    Warning: cannot apply tags to missing message: 987b9f975c44b57b8c9117b7ea934916@openconcept.ca
-    Warning: cannot apply tags to missing message: 007201c508a5$69044240$6601a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 03B6A33A-6B2B-11D9-AEC6-000D93343944@openconcept.ca
-    Warning: cannot apply tags to missing message: a29263e92b222edd9a5360e808c1175a@openconcept.ca
-    Warning: cannot apply tags to missing message: BAYC1-PASMTP0481B3FD589A058D4F3575B8C40@cez.ice
-    Warning: cannot apply tags to missing message: 00b401c5185b$e84231f0$6401a8c0@Heather
-    Warning: cannot apply tags to missing message: 011901c53b91$ab53cde0$6601a8c0@Heather
-    Warning: cannot apply tags to missing message: 00ab01c56fef$07c205b0$b1165146@virginie807e5x
-    Warning: cannot apply tags to missing message: 007701c5138c$2bcd2120$6401a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 42C1285A-6E30-11D9-B462-000D93343944@openconcept.ca
-    Warning: cannot apply tags to missing message: c6e0fb0e5e6f126d4aeba4b47fd08767@openconcept.ca
-    Warning: cannot apply tags to missing message: 13A357CE-6C05-11D9-BF97-000D93343944@openconcept.ca
-    Warning: cannot apply tags to missing message: 74a98267aa5bd778c108caa06b639f16@openconcept.ca
-    Warning: cannot apply tags to missing message: 5ff6eaa743b86548380ec614052db934@openconcept.ca
-    Warning: cannot apply tags to missing message: 000901c4fe3d$39b686a0$6501a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 3ef70a38335bebda4a0ecaa8c1cb3f6c@openconcept.ca
-    Warning: cannot apply tags to missing message: bf01584f23010aff2dc690e42c2517b4@openconcept.ca
-    Warning: cannot apply tags to missing message: 004301c50e23$197b1c70$6401a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 000001c4fe47$67324f60$6501a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 49b3fe0ac56cdc871e4b285c0fea1400@openconcept.ca
-    Warning: cannot apply tags to missing message: 9edced09a4aa53157517b6841b608005@openconcept.ca
-    Warning: cannot apply tags to missing message: 641dea3a42ed094d2c4ab5fbbd2c69e6@openconcept.ca
-    Warning: cannot apply tags to missing message: 83db9ff1a6af0287a7b98e2ae8bde2d9@openconcept.ca
-    Warning: cannot apply tags to missing message: 798D376B-AB70-4E03-B572-C873991D444C@gmail.com
-    Warning: cannot apply tags to missing message: 009d01c572a3$dff3a6d0$6401a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 430E19E8.4090603@reyero.net
-    Warning: cannot apply tags to missing message: 823A509E-BFF3-4ED7-831D-7BF406CF83CA@openconcept.ca
-    Warning: cannot apply tags to missing message: 060C6270-6A36-11D9-8FD2-000D93343944@openconcept.ca
-    Warning: cannot apply tags to missing message: bcbad02e937ba1d4d1de69084d2b7083@openconcept.ca
-    Warning: cannot apply tags to missing message: 8a88b1f78edd7984d64f2c27a2a63726@openconcept.ca
-    Warning: cannot apply tags to missing message: 000301c5737a$1935fca0$6401a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 15fad320817cd2f7215be74a2686da1b@openconcept.ca
-    Warning: cannot apply tags to missing message: 3FB7D70D-4639-47C3-B1FF-2D268B92F5DE@openconcept.ca
-    Warning: cannot apply tags to missing message: 230bee8079c68580ce8b928d94a398da@openconcept.ca
-    Warning: cannot apply tags to missing message: adb2bc8853c65ca758c458ee6e36cef1@openconcept.ca
-    Warning: cannot apply tags to missing message: 002c01c50f9a$31886610$6501a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 8006ce7bd376c4528040ec7bcc8decb4@openconcept.ca
-    Warning: cannot apply tags to missing message: d10952be2129c845c34b37406e8551d0@openconcept.ca
-    Warning: cannot apply tags to missing message: 007d01c5183b$26b9e020$6401a8c0@Heather
-    Warning: cannot apply tags to missing message: 000001c50337$799b4270$1a00a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 7b86080d227b2ad12c401981b155d1ff@openconcept.ca
-    Warning: cannot apply tags to missing message: 006601c56aa2$7f93dc50$c200a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 5c761ff70f15b77a8b396abeb7ce0604@openconcept.ca
-    Warning: cannot apply tags to missing message: !~!UENERkVCMDkAAQACAAAAAAAAAAAAAAAAABgAAAAAAAAAJWsLdJI9dE2by3G/V3gQHcKAAAAQAAAAyXKHyiKTo0ivUQRuFCpI4wEAAAAA@mazestudio.net
-    Warning: cannot apply tags to missing message: d25e722cfd7107a8f1437818dc85fcfa@openconcept.ca
-    Warning: cannot apply tags to missing message: a67826f3e84b001fc913756817c3f4c2@openconcept.ca
-    Warning: cannot apply tags to missing message: 4b22d62073054d6d4b8b9a4720559559@openconcept.ca
-    Warning: cannot apply tags to missing message: 005f01c578c7$8e9d5db0$6401a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: FD884134-6FA2-11D9-B462-000D93343944@openconcept.ca
-    Warning: cannot apply tags to missing message: 1c8e05719f1b976434f870f526757843@openconcept.ca
-    Warning: cannot apply tags to missing message: 000701c502ec$6bd3d7b0$6401a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 004201c50e21$8c97b7b0$6401a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: c7d50e51ed2b9b7910cddd5a84952d63@openconcept.ca
-    Warning: cannot apply tags to missing message: 002301c5086f$1790ba00$6601a8c0@MyLaptop
-    Warning: cannot apply tags to missing message: 6321fb43801dd5f2cf71884dea8e39c5@openconcept.ca
-    Warning: cannot apply tags to missing message: 427C3859-695C-4D55-9010-EFDCAD8FA88B@openconcept.ca
-    Warning: cannot apply tags to missing message: notmuch-sha1-d7ec112dea61c4f590f34151671a1ac2c1cace06
-    Warning: cannot apply tags to missing message: mailman.0.1482513100.18134.password-store@lists.zx2c4.com
-    Warning: cannot apply tags to missing message: mailman.0.1508792218.15356.people@lists.netdevconf.org
-    Warning: cannot apply tags to missing message: mailman.0.1509743320.1625.hostap@lists.infradead.org
-    Warning: cannot apply tags to missing message: mailman.0.1426991002.10426.ledger-smb-announce@lists.sourceforge.net
-    Warning: cannot apply tags to missing message: mailman.0.1434349074.1600379.debconf-announce@lists.debconf.org
-    Warning: cannot apply tags to missing message: mailman.0.1426990105.26776.rtir@lists.bestpractical.com
-    Warning: cannot apply tags to missing message: mailman.0.1426641392.23356.outages-announce@outages.org
-    Warning: cannot apply tags to missing message: 201807192352.w6JNq2AD006066@www3.voip.ms
-    Warning: cannot apply tags to missing message: notmuch-sha1-10840ac0107587e9f431dc60357bc9e282034fa6
-    Warning: cannot apply tags to missing message: notmuch-sha1-b7f4e192ef7f550bde54c806e1d147f15cbb82b3
-    Warning: cannot apply tags to missing message: notmuch-sha1-118a6aa53881cc11ebbf986ffbbcb873fc0afbd8
-    Warning: cannot apply tags to missing message: notmuch-sha1-973bb69e8f6bdcb104d2089515e782b4e95ae3a4
-    Warning: cannot apply tags to missing message: mailman.7.1317646801.26891.outages-discussion@outages.org
+    [...]
     Warning: cannot apply tags to missing message: mailman.2.1316793601.53477.sage-members@mailman.sage.org
-    Warning: cannot apply tags to missing message: notmuch-sha1-66b02bb369086c095d1fee9ab211826310009642
-    Warning: cannot apply tags to missing message: notmuch-sha1-9b3b1113e35ba2fda1491b6a20ce704c6d6e627f
-    Warning: cannot apply tags to missing message: notmuch-sha1-e53c4b17fc9621beb3b16adbe490b5e944ba50ec
-    Warning: cannot apply tags to missing message: notmuch-sha1-8a33fb82a593c779ac8aeb5fe2bfb3632c194134
-    Warning: cannot apply tags to missing message: notmuch-sha1-48d841b59781921146762e754ac2589fc04319ba
-    Warning: cannot apply tags to missing message: notmuch-sha1-0f2383b11054512fc02341d9bc0945bfe88ca845
-    Warning: cannot apply tags to missing message: notmuch-sha1-cc9e40f851b43a0ed13c06e75d5f9cb6ba68e0cf
-    Warning: cannot apply tags to missing message: notmuch-sha1-185ab7edbd1dbadfa0fffb739b45ff7a99666ce4
-    Warning: cannot apply tags to missing message: notmuch-sha1-374678e9a452ebfafcd8ea4a167fc762c4d1d00c
-    Warning: cannot apply tags to missing message: notmuch-sha1-ce8bea1731035c226753ea778178adbafba5a27c
-    Warning: cannot apply tags to missing message: notmuch-sha1-fe3c183caabf073600ee7d64319548d96148e173
-    Warning: cannot apply tags to missing message: notmuch-sha1-8a651984b79aaead0f75c30c4715e8d9fc8ec0bc
-    Warning: cannot apply tags to missing message: notmuch-sha1-fec1aaaad3b2aaa3a4a8c1ea438fc628f28df838
-    Warning: cannot apply tags to missing message: notmuch-sha1-b438f2d1dc2c580b834196f42f17d2ccb0c1f96e
-    Warning: cannot apply tags to missing message: notmuch-sha1-86f2c2c4d2fec24d17e99ad7c14a4ca7268fdbf2
-    Warning: cannot apply tags to missing message: notmuch-sha1-82cb293864a088c0442541522506e46dc0cec9f9
-    Warning: cannot apply tags to missing message: notmuch-sha1-20386be1d7f7a1fafe8a2ff2988611784409a7db
-    Warning: cannot apply tags to missing message: notmuch-sha1-b4d7f8a8c894de21aa7e2cc9e9962b29c05ca99e
-    Warning: cannot apply tags to missing message: notmuch-sha1-0e5bd571ba88423a1e9079d602c47d9aabc2d582
-    Warning: cannot apply tags to missing message: notmuch-sha1-6d7e48267b8fc279777d6490548129b9e9b9f7d4
-    Warning: cannot apply tags to missing message: notmuch-sha1-4fb1dbd84dfa90ea6ed39bc1af18b386c20e34ee
-    Warning: cannot apply tags to missing message: notmuch-sha1-2940634accfca6fdc0202a52c329b31a71086fe4
-    Warning: cannot apply tags to missing message: notmuch-sha1-fd2360e924a7178d997694b94e1577a27bc15cfa
-    Warning: cannot apply tags to missing message: notmuch-sha1-6f64187f20aede5979515d5661bd505821ed3dc4
-    Warning: cannot apply tags to missing message: notmuch-sha1-30f5866e81563aa945e4317f9be2a2cb35f794a8
-    Warning: cannot apply tags to missing message: notmuch-sha1-cb0dca48cce597240c1ebe53b3cc5b1ca2349267
-    Warning: cannot apply tags to missing message: notmuch-sha1-95b3fbe02e83e4959e2db2d49ff3f4dbbb7788d5
-    Warning: cannot apply tags to missing message: notmuch-sha1-a85d32ac8a8e1e89741095eec08550573937fc5b
+    Warning: cannot apply tags to missing message: mailman.7.1317646801.26891.outages-discussion@outages.org
     Warning: cannot apply tags to missing message: notmuch-sha1-000458df6e48d4857187a000d643ac971deeef47
-    Warning: cannot apply tags to missing message: notmuch-sha1-e549ec72173e748f9758fb5072d82eaa7a18c371
-    Warning: cannot apply tags to missing message: notmuch-sha1-e077733f32ce07805057d0d31d18a0698f18116e
-    Warning: cannot apply tags to missing message: notmuch-sha1-4ae716989a51baa563ea43a4498fd2f746c4016d
-    Warning: cannot apply tags to missing message: notmuch-sha1-3e78fa2e31773d139c73f7ac0e492c287bca8b6b
-    Warning: cannot apply tags to missing message: notmuch-sha1-c02a92c388e957ae78a1c48bbd311bb75ec3ad70
-    Warning: cannot apply tags to missing message: notmuch-sha1-6b75c40d596854a8f80e0d640b6217d9f9ed5e95

(Diff truncated)
almost finished
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index 16a9e43c..e7116212 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -392,17 +392,17 @@ Do a manual run:
 
     mbsync -a
 
-Copy the old notmuch database:
-
-    cp -a ~/Maildir-smd/.notmuch/xapian ~/Maildir/.notmuch/xapian
-
 Rebuild the notmuch database, as it will re-index *all* the messages,
 so it and will need to do a lot of work:
 
     notmuch new
 
-TODO: it might be faster to just scrap the database after a `notmuch
-dump`, reindex everything, then `notmuch restore`. The fresh indexing
+This should take around 25 minutes. Then restore the tags from backup:
+
+    pv notmuch.dump | notmuch restore
+
+We're doing a `notmuch new` from scratch because it's faster than
+doing it on top of the existing DB, surprisingly. The fresh indexing
 took:
 
     nov 19 15:08:54 angela notmuch[2521117]: Processed 384679 total files in 23m 41s (270 files/sec.).
@@ -423,6 +423,373 @@ If all is still well, enable the systemd service:
 
 Remove the `smd*` jobs from systemd and fix `notmuch-new.service`.
 
+During the migration, notmuch helpfully told me the full list of those
+lost messages:
+
+    Warning: cannot apply tags to missing message: notmuch-sha1-d0be3cf5f57defc75e6cbefaa0f468e7f8a2f49f
+    Warning: cannot apply tags to missing message: 20170923143147.BFEFC1A00AC@marcos.anarc.at
+    Warning: cannot apply tags to missing message: notmuch-sha1-2c9331b2fdde1bf2c7c8104fd6623712bd9dc19f
+    Warning: cannot apply tags to missing message: notmuch-sha1-4a21d84a7424640b53bab394f9d6819d0d482ae3
+    Warning: cannot apply tags to missing message: notmuch-sha1-ac6d0df1210717abf48c3c040ef2d922c408a294
+    Warning: cannot apply tags to missing message: notmuch-sha1-78c017379e7c2c350c545d3d9d7ffec241f9004e
+    Warning: cannot apply tags to missing message: notmuch-sha1-6537b24115699962b479b716778f9bebde4548aa
+    Warning: cannot apply tags to missing message: notmuch-sha1-a903e68fbeb8eec4c5cfd8aa74ea4f138db8a6b2
+    Warning: cannot apply tags to missing message: notmuch-sha1-f47de331cddef381a355c1e7a2b2b70478ba6b00
+    Warning: cannot apply tags to missing message: notmuch-sha1-ff9af4a8a7a03ff3b5d55a00728fe64be8b00eb6
+    Warning: cannot apply tags to missing message: notmuch-sha1-e4afd55ecb0c8dc026a1d37c514ce7d25e055b9c
+    Warning: cannot apply tags to missing message: notmuch-sha1-730c10bc421aa5e880c80459794333d42cd87372
+    Warning: cannot apply tags to missing message: notmuch-sha1-451b85cde55ae3e7dd0fd4258316008c301f1706
+    Warning: cannot apply tags to missing message: notmuch-sha1-793882a290834268e86c60941d9cd233af4d9755
+    Warning: cannot apply tags to missing message: notmuch-sha1-56a2874aec19b749745de3013ba52f86b91a0d01
+    Warning: cannot apply tags to missing message: notmuch-sha1-0eeb8f2779dbe40e20206b7aa95af3a434ded3e4
+    Warning: cannot apply tags to missing message: notmuch-sha1-a8f1f480e86e87c714e2f78732e308dc233cba9c
+    Warning: cannot apply tags to missing message: notmuch-sha1-e86d3afef3627f1c2b6769d20cbc946c070937f8
+    Warning: cannot apply tags to missing message: notmuch-sha1-e390fc067ef10fb401b63cc940bcbb164a1ee4bb
+    Warning: cannot apply tags to missing message: notmuch-sha1-a6d52472f2491dd87c7f044a8548f9025c6f16b5
+    Warning: cannot apply tags to missing message: 1117662302.429e2c5e5f380@67.18.121.132
+    Warning: cannot apply tags to missing message: 1117627371.429da3ebcf865@67.18.121.132
+    Warning: cannot apply tags to missing message: 1f2e235126095e5a5d4ef610669f11c0@openconcept.ca
+    Warning: cannot apply tags to missing message: a11a9cedaee1bbd816e1c0fb2b07ff63@openconcept.ca
+    Warning: cannot apply tags to missing message: 6ebc2221ca4c982f2d36ca3488fd4fc6@openconcept.ca
+    Warning: cannot apply tags to missing message: 00be01c57062$30838a00$b1165146@virginie807e5x
+    Warning: cannot apply tags to missing message: ece3ace394e2911a1cdcb9ab22bf6be5@openconcept.ca
+    Warning: cannot apply tags to missing message: 9f5e40b7bd8159842eeaf63eeadd7b21@openconcept.ca
+    Warning: cannot apply tags to missing message: 440BF6F8-6D75-11D9-9596-000D93343944@openconcept.ca
+    Warning: cannot apply tags to missing message: 7ff7dcd024a5a4c2472ab09a09c15a42@openconcept.ca
+    Warning: cannot apply tags to missing message: 00bd01c572c2$9690efb0$6401a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 2752b57076c1044362796aac295173d3@openconcept.ca
+    Warning: cannot apply tags to missing message: 5d1b07f0ac57e1588952c99feb53d770@openconcept.ca
+    Warning: cannot apply tags to missing message: efe05271c79f20e15b45d39cd99f0f97@openconcept.ca
+    Warning: cannot apply tags to missing message: 75CD2650-6A96-11D9-AEC6-000D93343944@openconcept.ca
+    Warning: cannot apply tags to missing message: 14a14ea4dffadfd71c71af508a739f8b@openconcept.ca
+    Warning: cannot apply tags to missing message: 007c01c5729e$78f55370$b1165146@virginie807e5x
+    Warning: cannot apply tags to missing message: 002d01c5065a$99d65130$6401a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: BAYC1-PASMTP02953B3192E37BB9FE2FADB88B0@CEZ.ICE
+    Warning: cannot apply tags to missing message: BDDD6AEA-566D-42C1-BE75-5B18828E4FD4@openconcept.ca
+    Warning: cannot apply tags to missing message: 20050216172343.GNNU1814.tomts9-srv.bellnexxia.net@mxmta.bellnexxia.net
+    Warning: cannot apply tags to missing message: 8382a6154cf79416c73f370cd574aaa8@openconcept.ca
+    Warning: cannot apply tags to missing message: c7db95f78233d5096ecc9f6b26f156da@openconcept.ca
+    Warning: cannot apply tags to missing message: 1117734753.429f4761e7f1a@67.18.121.132
+    Warning: cannot apply tags to missing message: 09ad34720a5658646c195bd9771306cc@openconcept.ca
+    Warning: cannot apply tags to missing message: 43582.200.169.20.98.1117717423.squirrel@www.koumbit.net
+    Warning: cannot apply tags to missing message: 006d01c51da6$c73a98d0$6401a8c0@Heather
+    Warning: cannot apply tags to missing message: b9240e32c34d4fd7c7849770efef86d6@openconcept.ca
+    Warning: cannot apply tags to missing message: 00a601c56084$26bf54b0$6401a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 17f296f546ac4d8236d49b9d632d7496@openconcept.ca
+    Warning: cannot apply tags to missing message: 0e8c83b49b94fe17cb10392c51fe9792@openconcept.ca
+    Warning: cannot apply tags to missing message: 6161b5ff70b86a78d743de4cde29e0e6@openconcept.ca
+    Warning: cannot apply tags to missing message: aa986ef2e1746e1d866b40f277c6e01a@openconcept.ca
+    Warning: cannot apply tags to missing message: F5086003-2917-4659-B7D2-66C62FCD4128@gmail.com
+    Warning: cannot apply tags to missing message: db803b0a46fbb724ecc864a70749e2eb@openconcept.ca
+    Warning: cannot apply tags to missing message: 1118397683.42a964f39c428@67.18.121.132
+    Warning: cannot apply tags to missing message: 1118175553.42a6014202765@67.18.121.132
+    Warning: cannot apply tags to missing message: 6819e6388394699d47285a6274ff3d03@openconcept.ca
+    Warning: cannot apply tags to missing message: 7D561B8C-F4A5-48AB-96E8-6AB888FB3952@gmail.com
+    Warning: cannot apply tags to missing message: 14a832ae6a1d9527b88630abe10eeb07@openconcept.ca
+    Warning: cannot apply tags to missing message: 16bc0ed6fa2798ce8fa0d26694d552a4@openconcept.ca
+    Warning: cannot apply tags to missing message: 1fca80b4c90c62faa3f05cb97e5f7fce@openconcept.ca
+    Warning: cannot apply tags to missing message: 987b9f975c44b57b8c9117b7ea934916@openconcept.ca
+    Warning: cannot apply tags to missing message: 007201c508a5$69044240$6601a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 03B6A33A-6B2B-11D9-AEC6-000D93343944@openconcept.ca
+    Warning: cannot apply tags to missing message: a29263e92b222edd9a5360e808c1175a@openconcept.ca
+    Warning: cannot apply tags to missing message: BAYC1-PASMTP0481B3FD589A058D4F3575B8C40@cez.ice
+    Warning: cannot apply tags to missing message: 00b401c5185b$e84231f0$6401a8c0@Heather
+    Warning: cannot apply tags to missing message: 011901c53b91$ab53cde0$6601a8c0@Heather
+    Warning: cannot apply tags to missing message: 00ab01c56fef$07c205b0$b1165146@virginie807e5x
+    Warning: cannot apply tags to missing message: 007701c5138c$2bcd2120$6401a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 42C1285A-6E30-11D9-B462-000D93343944@openconcept.ca
+    Warning: cannot apply tags to missing message: c6e0fb0e5e6f126d4aeba4b47fd08767@openconcept.ca
+    Warning: cannot apply tags to missing message: 13A357CE-6C05-11D9-BF97-000D93343944@openconcept.ca
+    Warning: cannot apply tags to missing message: 74a98267aa5bd778c108caa06b639f16@openconcept.ca
+    Warning: cannot apply tags to missing message: 5ff6eaa743b86548380ec614052db934@openconcept.ca
+    Warning: cannot apply tags to missing message: 000901c4fe3d$39b686a0$6501a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 3ef70a38335bebda4a0ecaa8c1cb3f6c@openconcept.ca
+    Warning: cannot apply tags to missing message: bf01584f23010aff2dc690e42c2517b4@openconcept.ca
+    Warning: cannot apply tags to missing message: 004301c50e23$197b1c70$6401a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 000001c4fe47$67324f60$6501a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 49b3fe0ac56cdc871e4b285c0fea1400@openconcept.ca
+    Warning: cannot apply tags to missing message: 9edced09a4aa53157517b6841b608005@openconcept.ca
+    Warning: cannot apply tags to missing message: 641dea3a42ed094d2c4ab5fbbd2c69e6@openconcept.ca
+    Warning: cannot apply tags to missing message: 83db9ff1a6af0287a7b98e2ae8bde2d9@openconcept.ca
+    Warning: cannot apply tags to missing message: 798D376B-AB70-4E03-B572-C873991D444C@gmail.com
+    Warning: cannot apply tags to missing message: 009d01c572a3$dff3a6d0$6401a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 430E19E8.4090603@reyero.net
+    Warning: cannot apply tags to missing message: 823A509E-BFF3-4ED7-831D-7BF406CF83CA@openconcept.ca
+    Warning: cannot apply tags to missing message: 060C6270-6A36-11D9-8FD2-000D93343944@openconcept.ca
+    Warning: cannot apply tags to missing message: bcbad02e937ba1d4d1de69084d2b7083@openconcept.ca
+    Warning: cannot apply tags to missing message: 8a88b1f78edd7984d64f2c27a2a63726@openconcept.ca
+    Warning: cannot apply tags to missing message: 000301c5737a$1935fca0$6401a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 15fad320817cd2f7215be74a2686da1b@openconcept.ca
+    Warning: cannot apply tags to missing message: 3FB7D70D-4639-47C3-B1FF-2D268B92F5DE@openconcept.ca
+    Warning: cannot apply tags to missing message: 230bee8079c68580ce8b928d94a398da@openconcept.ca
+    Warning: cannot apply tags to missing message: adb2bc8853c65ca758c458ee6e36cef1@openconcept.ca
+    Warning: cannot apply tags to missing message: 002c01c50f9a$31886610$6501a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 8006ce7bd376c4528040ec7bcc8decb4@openconcept.ca
+    Warning: cannot apply tags to missing message: d10952be2129c845c34b37406e8551d0@openconcept.ca
+    Warning: cannot apply tags to missing message: 007d01c5183b$26b9e020$6401a8c0@Heather
+    Warning: cannot apply tags to missing message: 000001c50337$799b4270$1a00a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 7b86080d227b2ad12c401981b155d1ff@openconcept.ca
+    Warning: cannot apply tags to missing message: 006601c56aa2$7f93dc50$c200a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 5c761ff70f15b77a8b396abeb7ce0604@openconcept.ca
+    Warning: cannot apply tags to missing message: !~!UENERkVCMDkAAQACAAAAAAAAAAAAAAAAABgAAAAAAAAAJWsLdJI9dE2by3G/V3gQHcKAAAAQAAAAyXKHyiKTo0ivUQRuFCpI4wEAAAAA@mazestudio.net
+    Warning: cannot apply tags to missing message: d25e722cfd7107a8f1437818dc85fcfa@openconcept.ca
+    Warning: cannot apply tags to missing message: a67826f3e84b001fc913756817c3f4c2@openconcept.ca
+    Warning: cannot apply tags to missing message: 4b22d62073054d6d4b8b9a4720559559@openconcept.ca
+    Warning: cannot apply tags to missing message: 005f01c578c7$8e9d5db0$6401a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: FD884134-6FA2-11D9-B462-000D93343944@openconcept.ca
+    Warning: cannot apply tags to missing message: 1c8e05719f1b976434f870f526757843@openconcept.ca
+    Warning: cannot apply tags to missing message: 000701c502ec$6bd3d7b0$6401a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 004201c50e21$8c97b7b0$6401a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: c7d50e51ed2b9b7910cddd5a84952d63@openconcept.ca
+    Warning: cannot apply tags to missing message: 002301c5086f$1790ba00$6601a8c0@MyLaptop
+    Warning: cannot apply tags to missing message: 6321fb43801dd5f2cf71884dea8e39c5@openconcept.ca
+    Warning: cannot apply tags to missing message: 427C3859-695C-4D55-9010-EFDCAD8FA88B@openconcept.ca
+    Warning: cannot apply tags to missing message: notmuch-sha1-d7ec112dea61c4f590f34151671a1ac2c1cace06
+    Warning: cannot apply tags to missing message: mailman.0.1482513100.18134.password-store@lists.zx2c4.com
+    Warning: cannot apply tags to missing message: mailman.0.1508792218.15356.people@lists.netdevconf.org
+    Warning: cannot apply tags to missing message: mailman.0.1509743320.1625.hostap@lists.infradead.org
+    Warning: cannot apply tags to missing message: mailman.0.1426991002.10426.ledger-smb-announce@lists.sourceforge.net
+    Warning: cannot apply tags to missing message: mailman.0.1434349074.1600379.debconf-announce@lists.debconf.org
+    Warning: cannot apply tags to missing message: mailman.0.1426990105.26776.rtir@lists.bestpractical.com
+    Warning: cannot apply tags to missing message: mailman.0.1426641392.23356.outages-announce@outages.org
+    Warning: cannot apply tags to missing message: 201807192352.w6JNq2AD006066@www3.voip.ms
+    Warning: cannot apply tags to missing message: notmuch-sha1-10840ac0107587e9f431dc60357bc9e282034fa6
+    Warning: cannot apply tags to missing message: notmuch-sha1-b7f4e192ef7f550bde54c806e1d147f15cbb82b3
+    Warning: cannot apply tags to missing message: notmuch-sha1-118a6aa53881cc11ebbf986ffbbcb873fc0afbd8
+    Warning: cannot apply tags to missing message: notmuch-sha1-973bb69e8f6bdcb104d2089515e782b4e95ae3a4
+    Warning: cannot apply tags to missing message: mailman.7.1317646801.26891.outages-discussion@outages.org
+    Warning: cannot apply tags to missing message: mailman.2.1316793601.53477.sage-members@mailman.sage.org
+    Warning: cannot apply tags to missing message: notmuch-sha1-66b02bb369086c095d1fee9ab211826310009642
+    Warning: cannot apply tags to missing message: notmuch-sha1-9b3b1113e35ba2fda1491b6a20ce704c6d6e627f
+    Warning: cannot apply tags to missing message: notmuch-sha1-e53c4b17fc9621beb3b16adbe490b5e944ba50ec
+    Warning: cannot apply tags to missing message: notmuch-sha1-8a33fb82a593c779ac8aeb5fe2bfb3632c194134
+    Warning: cannot apply tags to missing message: notmuch-sha1-48d841b59781921146762e754ac2589fc04319ba
+    Warning: cannot apply tags to missing message: notmuch-sha1-0f2383b11054512fc02341d9bc0945bfe88ca845
+    Warning: cannot apply tags to missing message: notmuch-sha1-cc9e40f851b43a0ed13c06e75d5f9cb6ba68e0cf
+    Warning: cannot apply tags to missing message: notmuch-sha1-185ab7edbd1dbadfa0fffb739b45ff7a99666ce4
+    Warning: cannot apply tags to missing message: notmuch-sha1-374678e9a452ebfafcd8ea4a167fc762c4d1d00c
+    Warning: cannot apply tags to missing message: notmuch-sha1-ce8bea1731035c226753ea778178adbafba5a27c
+    Warning: cannot apply tags to missing message: notmuch-sha1-fe3c183caabf073600ee7d64319548d96148e173
+    Warning: cannot apply tags to missing message: notmuch-sha1-8a651984b79aaead0f75c30c4715e8d9fc8ec0bc
+    Warning: cannot apply tags to missing message: notmuch-sha1-fec1aaaad3b2aaa3a4a8c1ea438fc628f28df838
+    Warning: cannot apply tags to missing message: notmuch-sha1-b438f2d1dc2c580b834196f42f17d2ccb0c1f96e
+    Warning: cannot apply tags to missing message: notmuch-sha1-86f2c2c4d2fec24d17e99ad7c14a4ca7268fdbf2
+    Warning: cannot apply tags to missing message: notmuch-sha1-82cb293864a088c0442541522506e46dc0cec9f9
+    Warning: cannot apply tags to missing message: notmuch-sha1-20386be1d7f7a1fafe8a2ff2988611784409a7db
+    Warning: cannot apply tags to missing message: notmuch-sha1-b4d7f8a8c894de21aa7e2cc9e9962b29c05ca99e
+    Warning: cannot apply tags to missing message: notmuch-sha1-0e5bd571ba88423a1e9079d602c47d9aabc2d582
+    Warning: cannot apply tags to missing message: notmuch-sha1-6d7e48267b8fc279777d6490548129b9e9b9f7d4
+    Warning: cannot apply tags to missing message: notmuch-sha1-4fb1dbd84dfa90ea6ed39bc1af18b386c20e34ee
+    Warning: cannot apply tags to missing message: notmuch-sha1-2940634accfca6fdc0202a52c329b31a71086fe4
+    Warning: cannot apply tags to missing message: notmuch-sha1-fd2360e924a7178d997694b94e1577a27bc15cfa
+    Warning: cannot apply tags to missing message: notmuch-sha1-6f64187f20aede5979515d5661bd505821ed3dc4
+    Warning: cannot apply tags to missing message: notmuch-sha1-30f5866e81563aa945e4317f9be2a2cb35f794a8
+    Warning: cannot apply tags to missing message: notmuch-sha1-cb0dca48cce597240c1ebe53b3cc5b1ca2349267
+    Warning: cannot apply tags to missing message: notmuch-sha1-95b3fbe02e83e4959e2db2d49ff3f4dbbb7788d5
+    Warning: cannot apply tags to missing message: notmuch-sha1-a85d32ac8a8e1e89741095eec08550573937fc5b
+    Warning: cannot apply tags to missing message: notmuch-sha1-000458df6e48d4857187a000d643ac971deeef47
+    Warning: cannot apply tags to missing message: notmuch-sha1-e549ec72173e748f9758fb5072d82eaa7a18c371
+    Warning: cannot apply tags to missing message: notmuch-sha1-e077733f32ce07805057d0d31d18a0698f18116e
+    Warning: cannot apply tags to missing message: notmuch-sha1-4ae716989a51baa563ea43a4498fd2f746c4016d

(Diff truncated)
remove old TODOs
diff --git a/blog/2020-10-19-google-authenticator-libpam.mdwn b/blog/2020-10-19-google-authenticator-libpam.mdwn
index 3ac2e1b0..84d4c596 100644
--- a/blog/2020-10-19-google-authenticator-libpam.mdwn
+++ b/blog/2020-10-19-google-authenticator-libpam.mdwn
@@ -80,7 +80,7 @@ Or, in Python:
 def convert_b32_b16(data_b32):
     remainder = len(data_b32) % 8
     if remainder > 0:
-        # XXX: assume 6 chars are missing, the actual padding may vary:
+        # assume 6 chars are missing, the actual padding may vary:
         # https://tools.ietf.org/html/rfc3548#section-5
         data_b32 += "======"
     data_b16 = base64.b32decode(data_b32)
diff --git a/services/upgrades/bullseye.mdwn b/services/upgrades/bullseye.mdwn
index c7b9bdff..89b3ac09 100644
--- a/services/upgrades/bullseye.mdwn
+++ b/services/upgrades/bullseye.mdwn
@@ -405,7 +405,7 @@ side, I ended up doing this ugly kludge:
 
     # remove packages gone from bullseye
     #
-    # XXX: we should really use < 11 here, but os.release.major is
+    # we should really use < 11 here, but os.release.major is
     # actually "bullseye/sid" now? ouch?
     #
     # remove this when we stop supporting buster

remove a copy of passhash.html that i somehow had left lying around
diff --git a/passhash.html b/passhash.html
deleted file mode 100644
index 8c4f54de..00000000
--- a/passhash.html
+++ /dev/null
@@ -1,1564 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head>
-
-
-
-
-<title>Password Hasher</title>
-<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-
-<style>
-<!--!skin:passhash-portable.css-->
-body {
-    background-color: #eeffee;
-    font-family: arial;
-}
-
-ul {
-    margin-left: 10px;
-    padding-left: 0px;
-    margin-top:0em;
-}
-
-li {
-    font-size: 10pt;
-    font-family: arial;
-    padding-top: .25em;
-    margin-top:0em;
-}
-
-.formfield {
-    font-size: 10pt;
-    font-family: serif;
-    width: 160px;
-}
-
-.formtable {
-    border: thin green solid;
-    padding: .3em;
-}
-
-.title {
-    font-size: 10pt;
-    font-family: arial;
-    font-weight: bold;
-    color: #6060a0;
-    text-align: center;
-}
-
-.result {
-    font-family: serif;
-    background-color: #d0d0f0;
-}
-
-.formlabel {
-    font-size: 9pt;
-    font-family: arial;
-    font-weight: bold;
-    color: #607888;
-    text-align: left;
-    width: 78px;
-}
-
-.optionbox {
-    border: thin silver solid;
-}
-
-.optionlabel {
-    font-size: 9pt;
-    font-family: arial;
-    font-weight: bold;
-    color: #607888;
-    text-align: left;
-}
-
-.optiontable {
-}
-
-.option {
-    font-size: 10pt;
-    font-family: arial;
-}
-
-.noteshead {
-    font-size: 10pt;
-    font-family: arial;
-    font-weight: bold;
-    padding-top: .5em;
-    color: #336633;
-}
-
-.prompt {
-    font-size: 10pt;
-    font-family: arial;
-    font-weight: normal;
-    color: #222288;
-    height: 40px;
-}
-
-.button {
-    width: 70px;
-}
-
-.password {
-    font-size: 10pt;
-    width: 160px;
-}
-</style>
-
-<script language="JavaScript" type="text/javascript">
-<!--!content:passhash-portable.js-->
-var browser = new Object();
-browser.version = parseInt(navigator.appVersion);
-browser.isNetscape = false;
-browser.isMicrosoft = false;
-if (navigator.appName.indexOf("Netscape") != -1) 
-    browser.isNetscape = true;
-else if (navigator.appName.indexOf("Microsoft") != -1)
-    browser.isMicrosoft = true;
-
-var siteTagLast = '';
-var masterKeyLast = '';
-
-function onLoad()
-{
-    if (browser.isMicrosoft)
-    {
-        document.getElementById('reveal').disabled = true;
-        document.getElementById('reveal-text').disabled = true;
-    }
-    document.getElementById('site-tag').focus();
-    setTimeout('checkChange()',1000);
-}
-
-function validate(form) 
-{
-    var siteTag   = document.getElementById('site-tag');
-    var masterKey = document.getElementById('master-key');
-    if (!siteTag.value)
-    {
-        siteTag.focus();
-        return false;
-    }
-    if (!masterKey.value)
-    {
-        masterKey.focus();
-        return false;
-    }
-    return true;
-}
-
-function update() 
-{
-    var siteTag   = document.getElementById('site-tag');
-    var masterKey = document.getElementById('master-key');
-    var hashWord  = document.getElementById('hash-word');
-    var submit    = document.getElementById('submit');
-    if (submit.value == 'Another')
-    {
-        siteTag.focus();
-        submit.value = 'OK';
-        hashWord.value = '';
-    }
-    else
-    {
-        //var hashapass = b64_hmac_sha1(masterKey.value, siteTag.value).substr(0,8);
-        var hashWordSize       = 8;
-        var requireDigit       = document.getElementById("digit").checked;
-        var requirePunctuation = document.getElementById("punctuation").checked;
-        var requireMixedCase   = document.getElementById("mixedCase").checked;
-        var restrictSpecial    = document.getElementById("noSpecial").checked;
-        var restrictDigits     = document.getElementById("digitsOnly").checked;
-        if      (document.getElementById("s6" ).checked) hashWordSize = 6;
-        else if (document.getElementById("s8" ).checked) hashWordSize = 8;
-        else if (document.getElementById("s10").checked) hashWordSize = 10;
-        else if (document.getElementById("s12").checked) hashWordSize = 12;
-        else if (document.getElementById("s14").checked) hashWordSize = 14;
-        else if (document.getElementById("s16").checked) hashWordSize = 16;
-        else if (document.getElementById("s18").checked) hashWordSize = 18;
-        else if (document.getElementById("s20").checked) hashWordSize = 20;
-        else if (document.getElementById("s22").checked) hashWordSize = 22;
-        else if (document.getElementById("s24").checked) hashWordSize = 24;
-        else if (document.getElementById("s26").checked) hashWordSize = 26;
-        hashWord.value = PassHashCommon.generateHashWord(
-                siteTag.value,
-                masterKey.value,
-                hashWordSize,
-                requireDigit,
-                requirePunctuation,
-                requireMixedCase,
-                restrictSpecial,
-                restrictDigits);
-        hashWord.focus();
-        submit.value = 'Another';
-    }

(Diff truncated)
tired of staring at pools, fuck it.
diff --git a/blog/2021-11-18-one-last-smd-crash.md b/blog/2021-11-18-one-last-smd-crash.md
index 3de51aea..90e2f293 100644
--- a/blog/2021-11-18-one-last-smd-crash.md
+++ b/blog/2021-11-18-one-last-smd-crash.md
@@ -309,6 +309,4 @@ messages and move on. They are still on the pool in the remote server
 and we can just hope the final full sync will not destroy them
 permanently. If we do, we have a backup and can restore them.
 
-TODO: inspect spool diff after migration.
-
 [[!tag draft]]

migration progress
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index d76596c6..16a9e43c 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -160,7 +160,23 @@ corrupted message that triggered [bug 999804](https://bugs.debian.org/cgi-bin/bu
 valgrind works around the bug, but adds a 50% performance cost, the
 full sync running in 1h35m.
 
-TODO: rerun tests with 1.4.3 after the bugfix. (in progress)
+A test with 1.4.3 yielded many crashes and stability issues (see
+below). Performance is fairly similar, considering that the new sync
+included the `register` folder with 4000 messages:
+
+    120.74user 213.19system 59:47.69elapsed 9%CPU (0avgtext+0avgdata 105420maxresident)k
+    29128inputs+28284376outputs (0major+45711minor)pagefaults 0swaps
+
+That is ~13GB in ~60 minutes, which gives us 28.3Mbps, fairly close to
+the 1.3 benchmark. Incrementals are also pretty similar, again
+considering the double-connect cost:
+
+    ===> multitime results
+    1: mbsync -a
+                Mean        Std.Dev.    Min         Median      Max
+    real        2.500       0.087       2.340       2.491       2.629       
+    user        0.718       0.037       0.679       0.711       0.793       
+    sys         0.322       0.024       0.284       0.320       0.365
 
 ## Great user interface
 
@@ -341,6 +357,7 @@ Make a backup on both the client and the server:
 
     cp -al Maildir Maildir-bak
     tar fc - Maildir | pv -s 13G > Maildir.tar
+    notmuch dump > notmuch.dump
 
 Then, the critical section begins.
 
@@ -357,8 +374,6 @@ moved out):
     rm -rf Maildir-mbsync
     mbsync -a
 
-TODO: we're at the full sync stage, complete the migration.
-
 This should take an hour on a gigabit link, much longer on
 remote. When that is done, move the mbsync dir in place:
 
@@ -377,6 +392,25 @@ Do a manual run:
 
     mbsync -a
 
+Copy the old notmuch database:
+
+    cp -a ~/Maildir-smd/.notmuch/xapian ~/Maildir/.notmuch/xapian
+
+Rebuild the notmuch database, as it will re-index *all* the messages,
+so it and will need to do a lot of work:
+
+    notmuch new
+
+TODO: it might be faster to just scrap the database after a `notmuch
+dump`, reindex everything, then `notmuch restore`. The fresh indexing
+took:
+
+    nov 19 15:08:54 angela notmuch[2521117]: Processed 384679 total files in 23m 41s (270 files/sec.).
+    nov 19 15:08:54 angela notmuch[2521117]: Added 372610 new messages to the database.
+
+While a reindexing on top of an existing database was going twice as
+slow, at about 120 files/sec.
+
 If all goes well, we're basically almost done. Try the same through
 systemd and watch the logs:
 
@@ -384,7 +418,8 @@ systemd and watch the logs:
 
 If all is still well, enable the systemd service:
 
-    systemctl --user enable mbsync.timer
+    systemctl --user enable mbsync.timer notmuch-new.service
+    systemctl --user start mbsync.timer
 
 Remove the `smd*` jobs from systemd and fix `notmuch-new.service`.
 

looked into sandboxing, failed
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index 89549d12..d76596c6 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -268,11 +268,15 @@ time of writing:
     [Install]
     WantedBy=default.target smd-pull.service smd-push.service
 
-TODO: add as much sandboxing as possible in systemd.
-
-TODO: an improvement over this would be to use [IMAP notify](https://wiki.archlinux.org/title/Isync#With_imapnotify) but
-neither [imapnotify](https://github.com/a-sk/node-imapnotify) nor [goimapnotify](https://gitlab.com/shackra/goimapnotify) seem to be packaged in
-Debian.
+I have briefly considered adding sandboxing in systemd to limit the
+blast radius of a possible `mbsync` vulnerability, but this is very
+limited in `systemd --user`: most `Protect*` fields are not accessible
+for example. I have also considered using an [apparmor
+profile](https://github.com/krathalan/apparmor-profiles/blob/master/profiles/mbsync) but that is not trivial because we need to allow SSH and
+only some parts of it...
+
+TODO: an improvement would be to use [IMAP notify](https://wiki.archlinux.org/title/Isync#With_imapnotify) but neither
+[imapnotify](https://github.com/a-sk/node-imapnotify) nor [goimapnotify](https://gitlab.com/shackra/goimapnotify) seem to be packaged in Debian.
 
 ## Password-less setup
 

sync with my running i3 config
diff --git a/software/desktop/i3.conf b/software/desktop/i3.conf
index a6f23782..6476ab68 100644
--- a/software/desktop/i3.conf
+++ b/software/desktop/i3.conf
@@ -204,7 +204,7 @@ bindsym $mod+q exec i3-power-menu
 #bindsym $mod+0 mode "mode_system"
 set $mode_system (l)ock, (e)xit, switch_(u)ser, (s)uspend, (h)ibernate, (r)eboot, (Shift+s)hutdown
 mode "mode_system" {
-bindsym l exec --no-startup-id xscreensaver-command -activate
+bindsym l exec --no-startup-id xset s activate
 bindsym s exec --no-startup-id i3exit suspend, mode "default"
 bindsym u exec --no-startup-id i3exit switch_user, mode "default"
 bindsym e exec --no-startup-id i3exit logout, mode "default"
@@ -255,28 +255,47 @@ bindsym $mod+minus scratchpad show
 
 # super-fast shortcuts of death everywhere
 bindsym $mod+y exec /home/anarcat/bin/e
-bindsym $mod+u exec pcmanfm
+# should open the home directory with the preconfigured file
+# manager. now what *that* will be is mystery!
+bindsym $mod+u exec xdg-open .
+#
+# the way to find out what xdg-open will do is:
+#
+# xdg-mime query default $(xdg-mime query filetype $ARG)
+#
+# directories are `inode/directory`, so to set it:
+#
+# $ xdg-mime default Thunar.desktop inode/directory
+#
+# and it is correctly set:
+#
+# $ xdg-mime query default inode/directory
+# Thunar.desktop
 bindsym $mod+c exec qalculate
 
 # rofi
-bindsym $mod+r exec rofi -show run
-bindsym $mod+F2 exec rofi -show ssh
+bindsym $mod+r exec /home/anarcat/bin/rofi-wrap -show run
+bindsym $mod+F2 exec /home/anarcat/bin/rofi-wrap -show ssh
 # until mosh falls back to SSH (https://github.com/mobile-shell/mosh/issues/731)
-bindsym $mod+F3 exec rofi -show ssh -ssh-client mosh
-bindsym $mod+g exec rofi -show window
-bindsym $mod+p exec /home/anarcat/bin/pass-rofi
+bindsym $mod+F3 exec /home/anarcat/bin/rofi-wrap -show ssh -ssh-client mosh
+bindsym $mod+g exec /home/anarcat/bin/rofi-wrap -show window
+bindsym $mod+p exec /home/anarcat/bin/rofi-wrap -show pass
+bindsym $mod+Shift+p exec env PASS_ROFI_MODE=type /home/anarcat/bin/rofi-wrap -show pass
 
 # screensaver panic button
-# TODO: consider i3lock + xautolock?
-bindsym Pause exec xscreensaver-command -lock
+bindsym Pause exec xset s activate
 # screenshot
-bindsym Print exec /home/anarcat/bin/publish -S
-bindsym Shift+Print exec /home/anarcat/bin/publish -S -t 7
+bindsym Print exec /home/anarcat/bin/publish -S --select
+bindsym Shift+Print exec /home/anarcat/bin/publish -S --select -t 7
+bindsym Control+Print exec /home/anarcat/bin/publish -S
 # multimedia keys
-bindsym XF86AudioMute exec pactl set-sink-mute $(pactl list short sinks | grep -E 'RUNNING|IDLE' | cut -f 1) toggle
-bindsym XF86AudioMicMute exec pactl set-source-mute $(pactl list short sources | grep -v monitor | cut -f 1) toggle
-bindsym XF86AudioLowerVolume exec pactl -- set-sink-volume $(pactl list short sinks | grep -E 'RUNNING|IDLE' | cut -f 1) -2%
-bindsym XF86AudioRaiseVolume exec pactl -- set-sink-volume $(pactl list short sinks | grep -E 'RUNNING|IDLE' | cut -f 1) +2%
+bindsym XF86AudioMute exec /home/anarcat/bin/i3-pa-mixer volume mute
+# see also https://git.joeyh.name/index.cgi/joey/home.git/tree/bin/mic_mute
+bindsym XF86AudioMicMute exec /home/anarcat/bin/i3-pa-mixer volume mute-mic
+# also use "shift-mute" as an alternative to mic mute, because there's no such keysym on WASD keyboards
+bindsym Shift+XF86AudioMute exec /home/anarcat/bin/i3-pa-mixer volume mute-mic
+bindsym XF86AudioLowerVolume exec /home/anarcat/bin/i3-pa-mixer volume down
+bindsym XF86AudioRaiseVolume exec /home/anarcat/bin/i3-pa-mixer volume up
 
 # brightness. needs this in /etc/X11/xorg.conf
 #
@@ -292,6 +311,19 @@ for_window [title="pop-up"] floating enable
 for_window [class="Xmessage"] floating enable
 for_window [class="Qalculate"] floating enable
 
+# more Vincent Bernat cargo-culting:
+# https://github.com/vincentbernat/i3wm-configuration/blob/master/config
+no_focus [window_type="splash"]
+#for_window [tiling] border pixel 3
+for_window [class="Nm-connection-editor"] floating enable
+#for_window [class="Shadow"] fullscreen enable
+for_window [window_role="PictureInPicture"] floating enable
+for_window [title="Firefox — Sharing Indicator"] border pixel 1, sticky enable, move position 20 ppt -5 px
+no_focus [title="Firefox — Sharing Indicator"]
+for_window [class="Pavucontrol"] floating enable
+
+#exec --no-startup-id /home/anarcat/bin/i3-load-layouts
+
 # those should be extracted from Xresources:
 # https://i3wm.org/docs/userguide.html#xresources
 
@@ -306,3 +338,40 @@ client.urgent           #002b36 #dc322f #fdf6e3 #002b36
 # unpainted windows
 client.background       #002b36
 # also considered, but rejected: https://github.com/acrisci/i3-style
+
+# Start i3bar to display a workspace bar (plus the system information i3status
+# finds out, if available)
+bar {
+        status_command py3status
+        position top
+        # obey Fitt's law, ie. reduce the empty space
+        tray_padding 0
+        # colors are documented here:
+        # https://i3wm.org/docs/userguide.html#_colors
+        # there's also some colors in ~/.config/i3status/config
+        colors {
+                # base03
+                background #002b36
+                # base0 - forground is status bar
+                statusline #839496
+                # this is for the focused monitor
+                # we don't distinguish those for now:
+                # focused_background #002b36
+                # focused_statusline #839496
+                # base01 - status bar separators
+                separator #586e75
+                # border, background, text: white, base02, base2
+                focused_workspace  #839496 #586e75 #eee8d5
+                # same, but white, base02, base01
+                active_workspace   #839496 #073642 #586e75
+                # base02, base03, base01
+                inactive_workspace #073642 #002b36 #586e75
+                # same, with red bg. test this with "sleep 3; echo -ne '\007'"
+                urgent_workspace   #073642 #dc322f #586e75
+                # alternative, from https://github.com/tobiaszwaszak/i3wm/blob/master/config
+                #focused_workspace  #b58900 #b58900 #002b36
+                #active_workspace   #586e75 #586e75 #002b36
+                #inactive_workspace #073642 #002b36 #839496
+                #urgent_workspace #dc322f #dc322f #fdf6e3
+        }
+}

move list of alternatives to new blog post
diff --git a/blog/2021-06-29-another-mail-crash.md b/blog/2021-06-29-another-mail-crash.md
index 1bb1b5a9..4e1dfb95 100644
--- a/blog/2021-06-29-another-mail-crash.md
+++ b/blog/2021-06-29-another-mail-crash.md
@@ -160,28 +160,7 @@ my entire mail spool that way.
 
 As [[mentioned
 before|blog/2021-03-22-email-crash/#workarounds-and-solutions]], there
-are other programs that sync mail. I'm looking at:
-
- * [offlineimap3](https://github.com/OfflineIMAP/offlineimap3): requires IMAP, used the py2 version in the past,
-   might just still work, first sync painful (IIRC), ways to tunnel
-   over SSH, see comment below
- * [isync/mbsync](http://isync.sf.net/): might be faster, I remember having trouble
-   switching from offlineimap to this, has support for TLS client
-   certs, running over SSH (e.g. [presumably](https://www.angio.net/misc/mail.html) with `Tunnel "ssh -C
-   -q imap.example.com /usr/lib/dovecot/imap"`), and generally has
-   good words from multiple Debian and notmuch people ([Arch tutorial](https://wiki.archlinux.org/title/Isync))
- * [getmail](http://pyropus.ca/software/getmail/): just downloads email, might not be enough
- * [nncp](http://www.nncpgo.org/): treat the local spool as another mail server, might not
-   be compatible with my "multiple clients" setup
- * [doveadm-sync](https://wiki2.dovecot.org/Tools/Doveadm/Sync): requires dovecot on both ends, but supports
-   using SSH to sync, <del>will try this next</del>, may have
-   performance problems, see comment below
- * [interimap](https://guilhem.org/interimap/): syncs two IMAP servers, apparently faster than
-   `doveadm` and `offlineimap`, but requires running an IMAP server
-   locally
- * [mail-sync](https://blog.hades.lkamp.de/mail-sync/): notify support, happens over any piped transport
-   (e.g. ssh), diff/patch system, requires binary on both ends,
-   mentions UUCP in the manpage, seems awfully complicated to setup,
-   mentions `rsmtp` which is a nice name for `rsendmail`
+are other programs that sync mail. See [[the mbsync vs OfflineIMAP
+review|2021-11-18-mbsync-vs-offlineimap]] the list of alternatives.
 
 [[!tag syncmaildir rsendmail email fail sysadmin debian-planet python-planet]]
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index 02c6afc1..89549d12 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -631,11 +631,36 @@ performance, I have not looked any deeper in those discrepancies.
 
 # other ideas
 
-considering:
-
- * [interimap](https://guilhem.org/interimap/), presumably faster than dovecot sync and offlineimap
- * [mail-sync](https://blog.hades.lkamp.de/mail-sync/)
- * [doveadm-sync](https://wiki2.dovecot.org/Tools/Doveadm/Sync), if we're going to setup a local imap server
-   anyways, might as well get familiar with this
+Those are all the options I have considered, in alphabetical order
+
+ * [doveadm-sync](https://wiki2.dovecot.org/Tools/Doveadm/Sync): requires dovecot on both ends, can tunnel over
+   SSH, [may have performance issues in incremental sync](https://anarc.at/blog/2021-06-29-another-mail-crash/#comment-2e8364e113d1d7b8415c8652f217cfff)
+ * [fdm](https://github.com/nicm/fdm): fetchmail replacement, IMAP/POP3/stdin/Maildir/mbox,NNTP
+   support, SOCKS support (for Tor), complex rules for delivering to
+   specific mailboxes, adding headers, piping to commands,
+   etc. discarded because no (real) support for keeping mail on the
+   server, and written in C
+ * [getmail](http://pyropus.ca/software/getmail/): fetchmail replacement, IMAP/POP3 support, supports
+   incremental runs, classification rules, Python
+ * [interimap](https://guilhem.org/interimap/): syncs two IMAP servers, [apparently faster](https://guilhem.org/interimap/benchmark.html) than
+   `doveadm` and `offlineimap`, but requires running an IMAP server
+   locally
+ * [isync/mbsync](http://isync.sf.net/): TLS client certs and SSH tunnels, fast,
+   incremental, IMAP/POP/Maildir support, multiple mailbox, trash and
+   recursion support, and generally has good words from multiple
+   Debian and notmuch people ([Arch tutorial](https://wiki.archlinux.org/title/Isync)), written in C,
+   review above
+ * [mail-sync](https://blog.hades.lkamp.de/mail-sync/): notify support, happens over any piped transport
+   (e.g. ssh), diff/patch system, requires binary on both ends,
+   mentions UUCP in the manpage, mentions `rsmtp` which is a nice name
+   for `rsendmail`. not evaluated because it seems awfully complex to
+   setup
+ * [nncp](http://www.nncpgo.org/): treat the local spool as another mail server, not really
+   compatible with my "multiple clients" setup
+ * [offlineimap3](https://github.com/OfflineIMAP/offlineimap3): requires IMAP, used the py2 version in the past,
+   might just still work, first sync painful (IIRC), ways to tunnel
+   over SSH, review above
+
+Most projects were not evaluated due to lack of time.
 
 [[!tag draft]]

add toc
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index d45385ae..02c6afc1 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -16,6 +16,8 @@ But I also evaluated OfflineIMAP which was resurrected from the Python
 
 Read on for the details.
 
+[[!toc levels=2]]
+
 # Benchmarking setup
 
 All programs were tested against a Dovecot 1:2.3.13+dfsg1-2 server,

explicitely mention stability issues
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index bc2e5e68..d45385ae 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -195,6 +195,25 @@ In other words:
 I like it, but I'm not sure how it's going to translate into useful
 information in a systemd service.
 
+
+## Stability issues
+
+The newer release in Debian bookworm (currently at 1.4.3) has major
+stability issues on full sync. I filed [bug 999804](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=999804) in Debian about
+this, which lead to a [long thread on the upstream mailing list](https://sourceforge.net/p/isync/mailman/isync-devel/thread/87a6i1fo5y.fsf%40angela.anarc.at/). I
+have found at least three distinct crashes that could be double-free
+bugs "[which might be exploitable in the worst case](https://sourceforge.net/p/isync/mailman/message/37385942/)", not a
+reassuring prospect.
+
+The thing is: mbsync is really fast, but the downside of that is that
+it's written in C, and with that comes a whole set of security
+issues. The [Debian security tracker](https://security-tracker.debian.org) has only [three CVEs](https://security-tracker.debian.org/tracker/source-package/isync) on
+isync, but the above issues show there could be many more.
+
+Reading the source code certainly did not make me very comfortable
+with trusting it with arbitrary data. I will definitely consider
+sandboxing it as much as possible in systemd.
+
 ## Automation with systemd
 
 [The Arch wiki](https://wiki.archlinux.org/title/Isync#Calling_mbsync_automatically) has instructions on how to setup mbsync as a
@@ -247,6 +266,7 @@ time of writing:
     [Install]
     WantedBy=default.target smd-pull.service smd-push.service
 
+TODO: add as much sandboxing as possible in systemd.
 
 TODO: an improvement over this would be to use [IMAP notify](https://wiki.archlinux.org/title/Isync#With_imapnotify) but
 neither [imapnotify](https://github.com/a-sk/node-imapnotify) nor [goimapnotify](https://gitlab.com/shackra/goimapnotify) seem to be packaged in

update test setup
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index ccee09d3..bc2e5e68 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -28,6 +28,17 @@ The [[server|hardware/server/marcos/]] is a custom build with a AMD
 Ryzen 5 2600 CPU, with a RAID-1 array made of two NVMe drives (Intel
 SSDPEKNW010T8 and WDC WDS100T2B0C).
 
+The mail spool I am testing against has almost 400k messages and 13GB:
+
+    $ notmuch count --exclude=false
+    372758
+    $ du -sh --exclude xapian Maildir
+    13G	Maildir
+
+The baseline we are comparing against is SMD (syncmaildir) which
+performs the sync in about 7-8 seconds (3.5 seconds for each push/pull
+command). Anything close to that or better is good enough.
+
 # mbsync
 
 The [isync](https://isync.sourceforge.io/) (AKA `mbsync`) project is written in C and supports

migration updates
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index d08abc81..ccee09d3 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -147,7 +147,7 @@ corrupted message that triggered [bug 999804](https://bugs.debian.org/cgi-bin/bu
 valgrind works around the bug, but adds a 50% performance cost, the
 full sync running in 1h35m.
 
-TODO: rerun tests with 1.4.3 after the bugfix.
+TODO: rerun tests with 1.4.3 after the bugfix. (in progress)
 
 ## Great user interface
 
@@ -236,8 +236,6 @@ time of writing:
     [Install]
     WantedBy=default.target smd-pull.service smd-push.service
 
-TODO: make sure I disable the `smd*.service` in `notmuch-new.service`
-when I disable the SMD sync.
 
 TODO: an improvement over this would be to use [IMAP notify](https://wiki.archlinux.org/title/Isync#With_imapnotify) but
 neither [imapnotify](https://github.com/a-sk/node-imapnotify) nor [goimapnotify](https://gitlab.com/shackra/goimapnotify) seem to be packaged in
@@ -316,10 +314,6 @@ Delete the corrupt message:
 
 It is still available in `id:87czmxfp7l.fsf@angela.anarc.at` as well.
 
-Move the old Maildir aside on the client:
-
-    angela$ mv Maildir Maildir-smd
-
 Rerun a full sync on the client (to test 1.4.3 after the corruption is
 moved out):
 
@@ -331,6 +325,7 @@ TODO: we're at the full sync stage, complete the migration.
 This should take an hour on a gigabit link, much longer on
 remote. When that is done, move the mbsync dir in place:
 
+    mv Maildir Maildir-smd
     mv Maildir-mbsync Maildir
 
 Fix the `.mbsyncrc` to write there:

complete offlineimap analysis
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index 0d95b66c..d08abc81 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -587,8 +587,19 @@ significantly slower than what you'd expect from a sync process. ~30
 seconds is long enough to make me impatient and distracted; 3 seconds,
 less so: I can wait and see the results almost immediately.
 
-TODO: analysis of the offlineimap dataset: data is missing here as
-well, more than mbsync.
+The OfflineIMAP mail spool is also missing quite a few messages as well:
+
+    anarcat@angela:~(main)$ find Maildir-offlineimap -type f -type f -a \! -name '.*' | wc -l 
+    381463
+    anarcat@angela:~(main)$ find Maildir -type f -type f -a \! -name '.*' | wc -l 
+    385247
+
+... although that's probably *all* either new messages or the
+`register` folder, so OfflineIMAP might actually be in a better
+position there. But digging in more, it seems like the actual
+per-folder diff is fairly similar to mbsync: a few messages missing
+here and there. Considering OfflineIMAP's instability and poor
+performance, I have not looked any deeper in those discrepancies.
 
 # other ideas
 

notmuch inspection
diff --git a/blog/2021-11-18-one-last-smd-crash.md b/blog/2021-11-18-one-last-smd-crash.md
index a0759775..3de51aea 100644
--- a/blog/2021-11-18-one-last-smd-crash.md
+++ b/blog/2021-11-18-one-last-smd-crash.md
@@ -264,6 +264,51 @@ surprised those messages are just skipped by the IMAP server because
 of corruption. Unfortunately, there's nothing on the Dovecot server
 logs that would explain the discrepancy.
 
-TODO: notmuch
+Here again, notmuch comes to the rescue. We can list all message IDs
+to figure out that discrepancy:
+
+    notmuch search --exclude=false --output=messages '*' | pv -s 18M | sort > Maildir-msgids
+    notmuch --config=.notmuch-config-mbsync search --exclude=false --output=messages '*' | pv -s 18M | sort > Maildir-mbsync-msgids
+
+And then we can see how many messages notmuch thinks are missing:
+
+    $ wc -l *msgids
+    372723 Maildir-mbsync-msgids
+    372752 Maildir-msgids
+
+That's 29 messages. Oddly, it doesn't exactly match the `find` output:
+
+    anarcat@angela:~(main)$ find Maildir-mbsync -type f -type f -a \! -name '.*' | wc -l 
+    385204
+    anarcat@angela:~(main)$ find Maildir -type f -type f -a \! -name '.*' | wc -l 
+    385241
+
+That is 10 more messages. Ugh. But actually, I know what those are:
+more misfiled messages, so the totals actually match.
+
+In the notmuch output, there's a lot of stuff like this:
+
+    id:notmuch-sha1-fb880d673e24f5dae71b6b4d825d4a0d5d01cde4
+
+Those are messages without a valid Message-ID. Notmuch (presumably)
+constructs one based on the file's checksum. Because the files differ
+between the IMAP server and the local mail spool (which is
+unfortunate, but possibly inevitable), those do not match. There are
+exactly the same number of those on both sides, so I'll go ahead and
+assume those are all accounted for. What remains are:
+
+    anarcat@angela:~(main)$ diff -u Maildir-mbsync-msgids Maildir-msgids  | grep '^\-[^-]' | grep -v sha1 | wc -l 
+    2
+    anarcat@angela:~(main)$ diff -u Maildir-mbsync-msgids Maildir-msgids  | grep '^\+[^+]' | grep -v sha1 | wc -l 
+    21
+    anarcat@angela:~(main)$ 
+
+ie. 21 missing from mbsync, and, surprisingly, 2 missing from the
+original mail spool. At this point, we're about ready to ignore those
+messages and move on. They are still on the pool in the remote server
+and we can just hope the final full sync will not destroy them
+permanently. If we do, we have a backup and can restore them.
+
+TODO: inspect spool diff after migration.
 
 [[!tag draft]]

more offlineimap performance numbers
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index 25580052..0d95b66c 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -526,7 +526,69 @@ already.
 If I have the patience to go through with this, I will post updates
 with the incremental times.
 
-TODO: complete full sync with newer release and test incrementals.
+The new release still crashes, except it does so at the very end,
+which is an improvement, I guess, since the mails do get transfered:
+
+```
+ *** Finished account 'Anarcat' in 511:12
+ERROR: Exceptions occurred during the run!
+ERROR: Exception parsing message with ID (<20190619152034.BFB8810E07A@marcos.anarc.at>) from imaplib (response type: bytes).
+ AttributeError: decoding with 'X-EUC-TW' codec failed (AttributeError: 'memoryview' object has no attribute 'decode')
+
+Traceback:
+  File "/usr/share/offlineimap3/offlineimap/folder/Base.py", line 810, in copymessageto
+    message = self.getmessage(uid)
+  File "/usr/share/offlineimap3/offlineimap/folder/IMAP.py", line 343, in getmessage
+    data = self._fetch_from_imap(str(uid), self.retrycount)
+  File "/usr/share/offlineimap3/offlineimap/folder/IMAP.py", line 910, in _fetch_from_imap
+    raise OfflineImapError(
+
+ERROR: Exception parsing message with ID (<40A270DB.9090609@alternatives.ca>) from imaplib (response type: bytes).
+ AttributeError: decoding with 'x-mac-roman' codec failed (AttributeError: 'memoryview' object has no attribute 'decode')
+
+Traceback:
+  File "/usr/share/offlineimap3/offlineimap/folder/Base.py", line 810, in copymessageto
+    message = self.getmessage(uid)
+  File "/usr/share/offlineimap3/offlineimap/folder/IMAP.py", line 343, in getmessage
+    data = self._fetch_from_imap(str(uid), self.retrycount)
+  File "/usr/share/offlineimap3/offlineimap/folder/IMAP.py", line 910, in _fetch_from_imap
+    raise OfflineImapError(
+
+ERROR: IMAP server 'RemoteAnarcat' does not have a message with UID '32686'
+
+Traceback:
+  File "/usr/share/offlineimap3/offlineimap/folder/Base.py", line 810, in copymessageto
+    message = self.getmessage(uid)
+  File "/usr/share/offlineimap3/offlineimap/folder/IMAP.py", line 343, in getmessage
+    data = self._fetch_from_imap(str(uid), self.retrycount)
+  File "/usr/share/offlineimap3/offlineimap/folder/IMAP.py", line 889, in _fetch_from_imap
+    raise OfflineImapError(reason, severity)
+
+Command exited with non-zero status 1
+8273.52user 983.80system 8:31:12elapsed 30%CPU (0avgtext+0avgdata 841936maxresident)k
+56376inputs+43247608outputs (811major+4972914minor)pagefaults 0swaps
+"offlineimap  -o " took 8 hours 31 mins 15 secs
+```
+
+This is 8h31m for transfering 12G, which is around 3.1Mbit/s. That is
+*nine* times slower than mbsync, almost an order of magnitude!
+
+Incrementals are also much slower:
+
+    ===> multitime results
+    1: sh -c "offlineimap -o || true"
+                Mean        Std.Dev.    Min         Median      Max
+    real        24.639      0.513       23.946      24.526      25.708      
+    user        23.912      0.473       23.404      23.795      24.947      
+    sys         1.743       0.105       1.607       1.729       2.002
+
+That is also an order of magnitude slower than mbsync, and
+significantly slower than what you'd expect from a sync process. ~30
+seconds is long enough to make me impatient and distracted; 3 seconds,
+less so: I can wait and see the results almost immediately.
+
+TODO: analysis of the offlineimap dataset: data is missing here as
+well, more than mbsync.
 
 # other ideas
 

mbsync migration procedure, in progress
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index be17cfe7..25580052 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -292,6 +292,70 @@ With SSH:
 
 Basically: 200ms slower. Tolerable.
 
+## Migrating
+
+First, disable SMD on all clients:
+
+    systemctl --user --now disable smd-pull.service smd-pull.timer smd-push.service smd-push.timer notmuch-new.service notmuch-new.timer
+
+Run `notmuch-sync-flagged` and `notmuch dump` everywhere.
+
+Do one last `smd-pull` and `smd-push` by hand everywhere.
+
+Make a backup on both the client and the server:
+
+    cp -al Maildir Maildir-bak
+    tar fc - Maildir | pv -s 13G > Maildir.tar
+
+Then, the critical section begins.
+
+Delete the corrupt message:
+
+    anarcat@marcos:~$ mv Maildir/.notmuch/cur/1536068601.M123540P18521Q127.curie:2, .
+    anarcat@marcos:~$ 
+
+It is still available in `id:87czmxfp7l.fsf@angela.anarc.at` as well.
+
+Move the old Maildir aside on the client:
+
+    angela$ mv Maildir Maildir-smd
+
+Rerun a full sync on the client (to test 1.4.3 after the corruption is
+moved out):
+
+    rm -rf Maildir-mbsync
+    mbsync -a
+
+TODO: we're at the full sync stage, complete the migration.
+
+This should take an hour on a gigabit link, much longer on
+remote. When that is done, move the mbsync dir in place:
+
+    mv Maildir-mbsync Maildir
+
+Fix the `.mbsyncrc` to write there:
+
+    sed -i 's#Inbox ~/Maildir-mbsync/#Inbox ~/Maildir/#' .mbsyncrc
+
+Enable full syncing by switching the `Create` and `Expunge` parameters
+to `Both`. Consider enabling `Remove Both` as well. Change to `Sync
+All`.
+
+Do a manual run:
+
+    mbsync -a
+
+If all goes well, we're basically almost done. Try the same through
+systemd and watch the logs:
+
+    systemctl --user start mbsync
+
+If all is still well, enable the systemd service:
+
+    systemctl --user enable mbsync.timer
+
+Remove the `smd*` jobs from systemd and fix `notmuch-new.service`.
+
 # offlineimap
 
 I've used [OfflineIMAP](https://github.com/OfflineIMAP/offlineimap3) for a long time before switching to SMD. I

confirm disk performance and that mbsync/dovecot is the bottleneck
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index 5b057d37..be17cfe7 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -114,7 +114,22 @@ It's not quite "line rate": the resulting mail spool was 12GB (which
 is a problem, see below), which turns out to be about 29Mbit/s and
 therefore not maxing the gigabit link. That said, it's possible disks
 were the bottleneck on either end, although I'd be surprised by that:
-both are NVMe drives, so that should easily saturate a gigabit link.
+both are NVMe drives, so that should easily saturate a gigabit
+link. And in fact, a remote backup of the mail spool achieves much
+faster transfer rate on disks, so I do not believe the server is to
+blame here:
+
+    anarcat@marcos:~$ tar fc - Maildir | pv -s 13G > Maildir.tar
+    15,0GiO 0:01:57 [ 131MiB/s] [===================================] 115%
+
+That's 131Mi**byyte** per second, vastly faster than the gigabit
+link. The client has similar performance:
+
+    anarcat@angela:~(main)$ tar fc - Maildir | pv -s 17G > Maildir.tar
+    16,2GiO 0:02:22 [ 116MiB/s] [==================================] 95%
+
+So yes, those disks should be able to saturate a gigabit link, they
+are not the bottleneck.
 
 The incremental runs are roughly 2 seconds, which is even *more*
 impressive:

fix first post title
diff --git a/blog/2021-11-18-one-last-smd-crash.md b/blog/2021-11-18-one-last-smd-crash.md
index f0126c6d..a0759775 100644
--- a/blog/2021-11-18-one-last-smd-crash.md
+++ b/blog/2021-11-18-one-last-smd-crash.md
@@ -1,6 +1,4 @@
-[[!meta title="one last email crash"]]
-
-TODO: title.
+[[!meta title="One last syncmaildir crash"]]
 
 My [syncmaildir](https://github.com/gares/syncmaildir) (SMD)
 [[setup|https://github.com/gares/syncmaildir]] failed me one too many

more offlineimap details
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index 6145213d..5b057d37 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -275,14 +275,26 @@ With SSH:
     user        0.753       0.043       0.645       0.766       0.804       
     sys         0.328       0.045       0.212       0.340       0.393
 
-Basically: 200ms more. Tolerable.
+Basically: 200ms slower. Tolerable.
 
 # offlineimap
 
-launched full sync, TODO: check how much time it took.
+I've used [OfflineIMAP](https://github.com/OfflineIMAP/offlineimap3) for a long time before switching to SMD. I
+don't exactly remember why I switched, but I do remember it was
+painfully slow, and would sometimes crash.
+
+It also kind of died in a fire when Python 2 stop being
+maintained. The main author moved on to a different project,
+[imapfw](http://imapfw.offlineimap.org/) which could serve as a framework to build IMAP clients,
+but never seemed to get back to the OfflineIMAP feature
+set. Thankfully, a new team of volunteers ported OfflineIMAP to Python
+3 and we can now test that new version to see if it is an improvement
+over mbsync.
 
 ## crash on full sync
 
+The first thing we notice when doing a full sync is this crash:
+
     Copy message from RemoteAnarcat:junk:
      ERROR: Copying message 30624 [acc: Anarcat]
       decoding with 'X-EUC-TW' codec failed (AttributeError: 'memoryview' object has no attribute 'decode')
@@ -427,7 +439,15 @@ possibly limited to the `bullseye` version of offlineimap3 (the lovely
 (the equally gorgeous `0.0~git20211018.e64c254+dfsg-1`) seems
 unaffected.
 
-TODO: redo with new release and test incrementals.
+I'm still in the process of doing a full sync. Considering the above
+took three hours to transfer a third of the data, it seems reasonable
+that a full sync is going to take an entire day, which is pretty bad
+already.
+
+If I have the patience to go through with this, I will post updates
+with the incremental times.
+
+TODO: complete full sync with newer release and test incrementals.
 
 # other ideas
 

systemd setup, mention imap notify
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index 65e6927f..6145213d 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -171,7 +171,62 @@ information in a systemd service.
 
 ## Automation with systemd
 
-TODO: hook up in systemd, e.g. [this arch doc](https://wiki.archlinux.org/title/Isync#Calling_mbsync_automatically).
+[The Arch wiki](https://wiki.archlinux.org/title/Isync#Calling_mbsync_automatically) has instructions on how to setup mbsync as a
+systemd service. It suggests using the `--verbose` (`-V`) flag which
+is a little intense here, as it outputs 1444 lines of messages.
+
+I have used the following `.service` file:
+
+    [Unit]
+    Description=Mailbox synchronization service
+    ConditionHost=!marcos
+    Wants=network-online.target
+    After=network-online.target
+
+    [Service]
+    Type=oneshot
+    ExecStart=/usr/bin/mbsync -a
+
+    [Install]
+    WantedBy=default.target
+    Wants=notmuch-new.service
+
+And the following `.timer`:
+
+    [Unit]
+    Description=Mailbox synchronization timer
+    ConditionHost=!marcos
+
+    [Timer]
+    OnBootSec=2m
+    OnUnitActiveSec=5m
+    Unit=mbsync.service
+
+    [Install]
+    WantedBy=timers.target
+
+Notice how we marked the `.service` to `Wants` notmuch, so that
+`notmuch new` gets triggered. This is `notmuch-new.service` at the
+time of writing:
+
+    [Unit]
+    Description=notmuch new
+    After=smd-pull.service smd-push.service
+
+    [Service]
+    Type=oneshot
+    Nice=10
+    ExecStart=/usr/bin/notmuch new
+
+    [Install]
+    WantedBy=default.target smd-pull.service smd-push.service
+
+TODO: make sure I disable the `smd*.service` in `notmuch-new.service`
+when I disable the SMD sync.
+
+TODO: an improvement over this would be to use [IMAP notify](https://wiki.archlinux.org/title/Isync#With_imapnotify) but
+neither [imapnotify](https://github.com/a-sk/node-imapnotify) nor [goimapnotify](https://gitlab.com/shackra/goimapnotify) seem to be packaged in
+Debian.
 
 ## Password-less setup
 

more mbsync setup instructions
diff --git a/blog/2021-11-18-mbsync-vs-offlineimap.md b/blog/2021-11-18-mbsync-vs-offlineimap.md
index 64c8f0c4..65e6927f 100644
--- a/blog/2021-11-18-mbsync-vs-offlineimap.md
+++ b/blog/2021-11-18-mbsync-vs-offlineimap.md
@@ -1,8 +1,44 @@
-# mbsync tests
+[[!meta title="mbsync vs OfflineIMAP"]]
 
-## complex configuration
+After recovering from my [[latest email
+crash|blog/2021-11-18-one-last-smd-crash]]
+([[previously|blog/2021-06-29-another-mail-crash]],
+[[previously|blog/2021-03-22-email-crash/]]), I had to figure out
+which tool I should be using. I had many options (mostly detailed in
+the [[second mail crash
+documentation|blog/2021-06-29-another-mail-crash]]), but I figured I
+would start with a popular one (`mbsync`) partly because it would
+allow me to keep my current "password-less" setup by using an SSH
+tunnel.
 
-I set this basic [isync](https://isync.sourceforge.io/) (AKA `mbsync`) configuration:
+But I also evaluated OfflineIMAP which was resurrected from the Python
+2 apocalypse, and because I had used it before, for a long time.
+
+Read on for the details.
+
+# Benchmarking setup
+
+All programs were tested against a Dovecot 1:2.3.13+dfsg1-2 server,
+running Debian bullseye. 
+
+The [[client|hardware/angela]] is a Purism 13v4 laptop with a Samsung
+SSD 970 EVO 1TB NVMe drive. 
+
+The [[server|hardware/server/marcos/]] is a custom build with a AMD
+Ryzen 5 2600 CPU, with a RAID-1 array made of two NVMe drives (Intel
+SSDPEKNW010T8 and WDC WDS100T2B0C).
+
+# mbsync
+
+The [isync](https://isync.sourceforge.io/) (AKA `mbsync`) project is written in C and supports
+syncing Maildir and IMAP folders, with possibly multiple replicas. I
+haven't tested this but I suspect it might be possible to sync between
+two IMAP servers as well. It supports partial mirorrs, message flags,
+full folder support, and "trash" functionality.
+
+## Complex configuration file
+
+I am using this `.mbsyncrc` configuration file:
 
     SyncState *
     Sync New ReNew Flags
@@ -43,18 +79,42 @@ I set this basic [isync](https://isync.sourceforge.io/) (AKA `mbsync`) configura
     # Sync the movement of messages between folders and deletions, add after making sure the sync works
     #Expunge Both
 
-The first critical thing to note is that the configuration file is
-pretty opaque. Long gone are the days where I would spend a long time
-reading a manual page to figure out the meaning of every option. If
-that's your thing, you might like [this one](https://isync.sourceforge.io/mbsync.html). But I'm more of a
-"EXAMPLES section" kind of person now, and I somehow couldn't find a
-sample file on the website. I started from the [Arch wiki one](https://wiki.archlinux.org/title/Isync#Configuring) but
-it's actually not great because it's made for Gmail (which is not a
-usual Dovecot server)
+Long gone are the days where I would spend a long time reading a
+manual page to figure out the meaning of every option. If that's your
+thing, you might like [this one](https://isync.sourceforge.io/mbsync.html). But I'm more of a "EXAMPLES
+section" kind of person now, and I somehow couldn't find a sample file
+on the website. I started from the [Arch wiki one](https://wiki.archlinux.org/title/Isync#Configuring) but it's
+actually not great because it's made for Gmail (which is not a usual
+Dovecot server). So a sample config file in the manpage would be a
+great addition. Thankfully, the Debian packages ships one in
+`/usr/share/doc/isync/examples/mbsyncrc.sample` but I only found that
+after I wrote my configuration. It was still useful and I recommend
+people take a look if they want to understand the syntax.
+
+Also, that syntax is a little overly complicated. For example, `Far`
+needs colons, like:
+
+    Far :anarcat-remote:
+
+Why? That seems just too complicated. I also found that sections are
+not clearly identified: `IMAPAccount` and `Channel` mark section
+beginnings, for example. There are also weird ordering issues: the
+`SyncState` option needs to be before `IMAPAccount`, presumably
+because it's global.
+
+Using a more standard format like .INI or TOML would improve things
+greatly here.
 
 ## stellar performance
 
-The full sync too 56 minutes and 6 seconds, which is impressive.
+The full sync of my 300,000+ messages (12GB) took 56 minutes and 6
+seconds, which is impressive.
+
+It's not quite "line rate": the resulting mail spool was 12GB (which
+is a problem, see below), which turns out to be about 29Mbit/s and
+therefore not maxing the gigabit link. That said, it's possible disks
+were the bottleneck on either end, although I'd be surprised by that:
+both are NVMe drives, so that should easily saturate a gigabit link.
 
 The incremental runs are roughly 2 seconds, which is even *more*
 impressive:
@@ -66,25 +126,17 @@ impressive:
     user        0.660       0.040       0.592       0.661       0.722       
     sys         0.338       0.033       0.268       0.341       0.387    
 
-It's not quite "line rate": the resulting mail spool was 12GB (which
-is a problem, see below), which turns out to be about 29Mbit/s and
-therefore not maxing the gigabit link. That said, it's possible disks
-were the bottleneck on either end, although I'd be surprised by that:
-both are NVMe drives, so that should easily saturate a gigabit link.
-
-Those tests were performed with isync 1.3.0-2.2 on Debian bullseye
-with a Dovecot 1:2.3.13+dfsg1-2 server, also on bullseye. The
-[[client|hardware/angela]] is a Purism 13v4 laptop with a Samsung SSD
-970 EVO 1TB NVMe drive. The [[server|hardware/server/marcos/]] is a
-custom build with a AMD Ryzen 5 2600 CPU, with a RAID-1 array made of
-two NVMe drives (Intel SSDPEKNW010T8 and WDC WDS100T2B0C).
+Those tests were performed with isync 1.3.0-2.2 on Debian
+bullseye. Tests with a newer isync release failed because of a
+corrupted message that triggered [bug 999804](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=999804). Running 1.4.3 under
+valgrind works around the bug, but adds a 50% performance cost, the
+full sync running in 1h35m.
 
-Tests with a newer isync release failed because of a corrupted message
-that triggered [bug 999804](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=999804).
+TODO: rerun tests with 1.4.3 after the bugfix.
 
-## great UI
+## Great user interface
 
-Compared to offlineimap and (ahem) smd, the mbsync UI is kind of neat:
+Compared to offlineimap and (ahem) SMD, the mbsync UI is kind of neat:
 
     anarcat@angela:~(main)$ mbsync -a
     Notice: Master/Slave are deprecated; use Far/Near instead.
@@ -117,10 +169,59 @@ In other words:
 I like it, but I'm not sure how it's going to translate into useful
 information in a systemd service.
 
-## automation
+## Automation with systemd
 
 TODO: hook up in systemd, e.g. [this arch doc](https://wiki.archlinux.org/title/Isync#Calling_mbsync_automatically).
 
+## Password-less setup
+
+The sample file suggests this should work:
+
+    IMAPStore remote
+    Tunnel "ssh -q host.remote.com /usr/sbin/imapd"
+
+Add `BatchMode`, restrict to `IdentitiesOnly`, provide a password-less
+key just for this, add compression (`-C`), find the Dovecot `imap`
+binary, and you get this:
+    
+    IMAPAccount anarcat-tunnel
+    Tunnel "ssh -o BatchMode=yes -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_mbsync -o HostKeyAlias=shell.anarc.at -C anarcat@imap.anarc.at /usr/lib/dovecot/imap"
+
+And it actually seems to work:
+
+    $ mbsync -a
+    Notice: Master/Slave are deprecated; use Far/Near instead.
+    C: 0/2  B: 0/1  F: +0/0 *0/0 #0/0  N: +0/0 *0/0 #0/0imap(anarcat): Error: net_connect_unix(/run/dovecot/stats-writer) failed: Permission denied
+    C: 2/2  B: 205/205  F: +0/0 *0/0 #0/0  N: +1/1 *3/3 #0/0imap(anarcat)<1611280><90uUOuyElmEQlhgAFjQyWQ>: Info: Logged out in=10808 out=15396642 deleted=0 expunged=0 trashed=0 hdr_count=0 hdr_bytes=0 body_count=1 body_bytes=8087
+
+It's a bit noisy, however. `dovecot/imap` doesn't have a "usage" to
+speak of, but even the source code doesn't hint at a way to disable
+that `Error` message, so that's unfortunate. That socket is owned by
+`root:dovecot` so presumably Dovecot runs the `imap` process as
+`$user:dovecot`, which we can't do here. Oh well?
+
+Interestingly, the SSH setup is not faster than IMAP. 
+
+With IMAP:
+
+    ===> multitime results
+    1: mbsync -a
+                Mean        Std.Dev.    Min         Median      Max
+    real        2.367       0.065       2.220       2.376       2.458       
+    user        0.793       0.047       0.731       0.776       0.871       
+    sys         0.426       0.040       0.364       0.434       0.476
+
+With SSH:
+
+    ===> multitime results
+    1: mbsync -a
+                Mean        Std.Dev.    Min         Median      Max
+    real        2.515       0.088       2.274       2.532       2.594       
+    user        0.753       0.043       0.645       0.766       0.804       
+    sys         0.328       0.045       0.212       0.340       0.393
+
+Basically: 200ms more. Tolerable.
+
 # offlineimap
 
 launched full sync, TODO: check how much time it took.

split blog post in two, add details
diff --git a/blog/2021-11-16-mta-migration.md b/blog/2021-11-16-mta-migration.md
deleted file mode 100644
index 866586b5..00000000
--- a/blog/2021-11-16-mta-migration.md
+++ /dev/null
@@ -1,349 +0,0 @@
-[[!meta title="replacing syncmaildir with ... TODO"]]
-
-[[!toc levels=3]]
-
-My [syncmaildir](https://github.com/gares/syncmaildir) [[setup|https://github.com/gares/syncmaildir]]
-failed me one too many times. This is the painful story of how I
-switch mail transfer agents.
-
-# resurrecting my IMAP mail spool
-
-So I'm probably going back to IMAP to sync my mail. I had two many
-crashes with my current mail setup
-([[previously|blog/2021-06-29-another-mail-crash]],
-[[previously|blog/2021-03-22-email-crash/]]) and on monday it just
-started failing with this error:
-
-    nov 15 16:12:19 angela systemd[2305]: Starting pull emails with syncmaildir...
-    nov 15 16:12:22 angela systemd[2305]: smd-pull.service: Succeeded.
-    nov 15 16:12:22 angela systemd[2305]: Finished pull emails with syncmaildir.
-    nov 15 16:14:08 angela systemd[2305]: Starting pull emails with syncmaildir...
-    nov 15 16:14:11 angela systemd[2305]: smd-pull.service: Main process exited, code=exited, status=1/FAILURE
-    nov 15 16:14:11 angela systemd[2305]: smd-pull.service: Failed with result 'exit-code'.
-    nov 15 16:14:11 angela systemd[2305]: Failed to start pull emails with syncmaildir.
-    nov 15 16:16:14 angela systemd[2305]: Starting pull emails with syncmaildir...
-    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: Network error.
-    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: Unable to get any data from the other endpoint.
-    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: This problem may be transient, please retry.
-    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: Hint: did you correctly setup the SERVERNAME variable
-    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: on your client? Did you add an entry for it in your ssh
-    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: configuration file?
-    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: Network error
-    nov 15 16:16:17 angela smd-pull[27188]: register: smd-client@localhost: TAGS: error::context(handshake) probable-cause(network) human-intervention(avoidable) suggested-actions(retry)
-    nov 15 16:16:17 angela systemd[2305]: smd-pull.service: Main process exited, code=exited, status=1/FAILURE
-    nov 15 16:16:17 angela systemd[2305]: smd-pull.service: Failed with result 'exit-code'.
-    nov 15 16:16:17 angela systemd[2305]: Failed to start pull emails with syncmaildir.
-
-What is frustrating here is that there's no network error. Everything
-was working fine and then one minute to the next it starts
-failing. Running the command by hand I did see a different message,
-but now I have lost it in my backlog. It had something to do with a
-filename being too long, and I gave up debugging after a while. In a
-fit of rage I started this blog post and experimenting with
-alternatives, which led me down a lot of rabbit holes.
-
-## mailbox corruption
-
-Trying to sync over IMAP led to many problems like:
-
-    nov 16 15:31:27 marcos dovecot[3621800]: imap(anarcat)<3630489><wAmSzO3QZtfAqAB1>: Error: Mailbox junk: Maildir filename has wrong W value, renamed the file from /home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495,W=2578:2,S to /home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495:2,S
-    nov 16 15:31:27 marcos dovecot[3621800]: imap(anarcat)<3630489><wAmSzO3QZtfAqAB1>: Error: Mailbox junk: Deleting corrupted cache record uid=1582: UID 1582: Broken virtual size in mailbox junk: read(/home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495,W=2578:2,S): FETCH BODY[] got too little data: 2540 vs 2578
-
-and:
-
-    nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: UID=19288: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288) (read reason=mail stream)
-    nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: Deleting corrupted cache record uid=19288: UID 19288: Broken physical size in mailbox Sent: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288)
-    nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: UID=19288: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288) (read reason=)
-    nov 16 13:53:08 marcos dovecot[3520770]: imap-login: Panic: epoll_ctl(del, 7) failed: Bad file descriptor
-
-At least the first error was automatically healed by Dovecot. The
-problem is that the `FETCH` command then fails, so you need to
-constantly restart `mbsync` with a silly thing like:
-
-    while ! mbsync -a; do sleep 1; done
-
-The second one is much harder to fix, because dovecot does *not*
-self-heal that one. I wrote an extensive [fix script](https://gitlab.com/anarcat/scripts/-/blob/main/dovecot-fix-size-cache.py) for those two
-errors (because the above loop would have actually taken forever). I
-did read a lot on the [Dovecot documentation on the maildir format](https://doc.dovecot.org/admin_manual/mailbox_formats/maildir/).
-
-And no, [rebuilding the index files](https://dovecot.org/pipermail/dovecot/2019-June/116227.html) didn't work. Also tried
-`doveadm force-resync -u anarcat` which didn't do anything.
-
-In the end I also had to do:
-
-    service dovecot stop ; find -name 'dovecot*' -delete; service dovecot start
-
-Which would have totally broken any existing clients.
-
-## incoherences between maildir and IMAP
-
-Unfortunately, the first mbsync was incomplete as it's missing about
-15,000 mails:
-
-    anarcat@angela:~(main)$ find Maildir -type f | wc -l 
-    384836
-    anarcat@angela:~(main)$ find Maildir-mbsync/ -type f -a \! -name '.*' | wc -l 
-    369221
-
-The analysis and repairs below show that mbsync is *probably* not at
-cause, but a full resync was restarted to verify that (TODO).
-
-It's actually 26 folders with different sizes, which can be found
-with:
-
-    for folder in * .[^.]* ; do 
-      printf "%s\t%d\n" $folder $(find "$folder" -type f -a \! -name '.*' | wc -l );
-    done
-
-The special `\! -name '.*'` bit is to ignore the mbsync metadata,
-which leaves `.uidvalidity` and `.mbsyncstate` in every folder. The
-difference is minor (about 200 files) but it makes looking at the
-differences much harder.
-
-Here is what the diff looks like:
-
-    --- Maildir-list	2021-11-17 20:42:36.504246752 -0500
-    +++ Maildir-mbsync-list	2021-11-17 20:18:07.731806601 -0500
-    @@ -6,16 +6,15 @@
-    [...]
-     .Archives	1
-     .Archives.2010	3553
-    -.Archives.2011	3583
-    -.Archives.2012	12593
-    +.Archives.2011	3582
-    +.Archives.2012	620
-     .Archives.2013	8576
-     .Archives.2014	11057
-    -.Archives.2015	8173
-    +.Archives.2015	8165
-     .Archives.2016	54
-     .band	34
-     .bitbuck	1
-    @@ -38,13 +37,12 @@
-     .couchsurfers	2
-    -cur	11285
-    +cur	11280
-     .current	130
-     .cv	2
-     .debbug	262
-    -.debian	37544
-    -drafts	1
-    -.Drafts	4
-    +.debian	37533
-    +.Drafts	2
-     .drone	241
-     .drupal	188
-     .drupal-devel	303
-    [...]
-
-It's a bit all over the place, but we can already notice some huge
-diffs, for example in the `Archives` folders. As it turns out, at
-least 12,000 of those missing mails were actually misfiled: instead of
-being in the `Maildir/.Archives.2012/cur` folder, they were *directly*
-in `Maildir/.Archives.2012/`. This is something that doesn't matter
-for smd (and possibly for notmuch?) but that definitely matters to
-Dovecot and therefore mbsync... After moving those files around, we
-get to a much more reasonable:
-
-    anarcat@angela:~(main)$ find Maildir-mbsync/  -type f -a \! -name '.*' | wc -l 
-    381196
-    anarcat@angela:~(main)$ find Maildir/  -type f -a \! -name '.*' | wc -l 
-    385053
-
-The problem with *those* 4,000 (still) missing mails is that they're
-much harder to track. Take, for example, `.Archives.2011`: it's a
-single file missing, out of 3,582. And the files are not identical:
-the checksums don't match after going through the IMAP transport, so
-we can't use a tool like [hashdeep](http://md5deep.sourceforge.net/) to compare the trees and find
-why that one file is missing.
-
-One big chunk of the 4000, however, is a special folder called
-`register` in my spool, which I was syncing separately. That actually
-covers 3,700 of those messages, so I actually have a more modest 300
-messages to figure out. After syncing *those* messages, I end up with
-the measly little:
-
-    anarcat@angela:~(main)$ find Maildir-mbsync/  -type f -a \! -name '.*' | wc -l 
-    384900
-    anarcat@angela:~(main)$ find Maildir/  -type f -a \! -name '.*' | wc -l 
-    385059
-
-Argh. still 160 mails out of sync. After *more* digging, I have found
-131 mails in the `tmp/` directories of the *client*'s
-mailspool. Mysterious! On the server side, it's even *more* files, and
-*not* the same ones. Possible that those were mails that were left
-there during a failed delivery of some sort, during a power failure or
-some sort of crash? Who knows.
-
-The first thing to do with those is to cleanup a bunch of empty files
-(21 on angela):
-
-    find .[^.]*/tmp -type f -empty -delete
-
-As *that* turns out, they are *all* duplicates, in the sense that
-notmuch can easily find a copy of files with the same message ID in
-its database. In other words, this hairy command returns nothing
-
-    find .[^.]*/tmp -type f | while read path; do 
-      grep ^Message-ID "$path";
-    done | sed 's/Message-ID: //;s/[<>]//g' | while read msgid ; do
-      notmuch search --output=files id:$msgid ;
-    done | grep tmp
-
-Well, that was actually pretty naive because `notmuch search` will

(Diff truncated)
move tag back to the EOF
diff --git a/blog/2021-11-16-mta-migration.md b/blog/2021-11-16-mta-migration.md
index 3d089784..866586b5 100644
--- a/blog/2021-11-16-mta-migration.md
+++ b/blog/2021-11-16-mta-migration.md
@@ -337,8 +337,6 @@ TODO: hook up in systemd, e.g. [this arch doc](https://wiki.archlinux.org/title/
 
 launched full sync, TODO: check how much time it took.
 
-[[!tag draft]]
-
 # other ideas
 
 considering:
@@ -347,3 +345,5 @@ considering:
  * [mail-sync](https://blog.hades.lkamp.de/mail-sync/)
  * [doveadm-sync](https://wiki2.dovecot.org/Tools/Doveadm/Sync), if we're going to setup a local imap server
    anyways, might as well get familiar with this
+
+[[!tag draft]]

expand a bit
diff --git a/blog/2021-11-16-mta-migration.md b/blog/2021-11-16-mta-migration.md
index 402e029a..3d089784 100644
--- a/blog/2021-11-16-mta-migration.md
+++ b/blog/2021-11-16-mta-migration.md
@@ -1,34 +1,80 @@
+[[!meta title="replacing syncmaildir with ... TODO"]]
+
 [[!toc levels=3]]
 
-TODO: link to [[previously|blog/2021-06-29-another-mail-crash]] and other
+My [syncmaildir](https://github.com/gares/syncmaildir) [[setup|https://github.com/gares/syncmaildir]]
+failed me one too many times. This is the painful story of how I
+switch mail transfer agents.
 
 # resurrecting my IMAP mail spool
-## mailbox corruption
-
-TODO: expand on wtf was going on here.
-
-[maildir format](https://doc.dovecot.org/admin_manual/mailbox_formats/maildir/)
-
-[fix script](https://gitlab.com/anarcat/scripts/-/blob/main/dovecot-fix-size-cache.py)
 
-[rebuilding the index files](https://dovecot.org/pipermail/dovecot/2019-June/116227.html) didn't work
+So I'm probably going back to IMAP to sync my mail. I had two many
+crashes with my current mail setup
+([[previously|blog/2021-06-29-another-mail-crash]],
+[[previously|blog/2021-03-22-email-crash/]]) and on monday it just
+started failing with this error:
+
+    nov 15 16:12:19 angela systemd[2305]: Starting pull emails with syncmaildir...
+    nov 15 16:12:22 angela systemd[2305]: smd-pull.service: Succeeded.
+    nov 15 16:12:22 angela systemd[2305]: Finished pull emails with syncmaildir.
+    nov 15 16:14:08 angela systemd[2305]: Starting pull emails with syncmaildir...
+    nov 15 16:14:11 angela systemd[2305]: smd-pull.service: Main process exited, code=exited, status=1/FAILURE
+    nov 15 16:14:11 angela systemd[2305]: smd-pull.service: Failed with result 'exit-code'.
+    nov 15 16:14:11 angela systemd[2305]: Failed to start pull emails with syncmaildir.
+    nov 15 16:16:14 angela systemd[2305]: Starting pull emails with syncmaildir...
+    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: Network error.
+    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: Unable to get any data from the other endpoint.
+    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: This problem may be transient, please retry.
+    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: Hint: did you correctly setup the SERVERNAME variable
+    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: on your client? Did you add an entry for it in your ssh
+    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: configuration file?
+    nov 15 16:16:17 angela smd-pull[27178]: smd-client: ERROR: Network error
+    nov 15 16:16:17 angela smd-pull[27188]: register: smd-client@localhost: TAGS: error::context(handshake) probable-cause(network) human-intervention(avoidable) suggested-actions(retry)
+    nov 15 16:16:17 angela systemd[2305]: smd-pull.service: Main process exited, code=exited, status=1/FAILURE
+    nov 15 16:16:17 angela systemd[2305]: smd-pull.service: Failed with result 'exit-code'.
+    nov 15 16:16:17 angela systemd[2305]: Failed to start pull emails with syncmaildir.
+
+What is frustrating here is that there's no network error. Everything
+was working fine and then one minute to the next it starts
+failing. Running the command by hand I did see a different message,
+but now I have lost it in my backlog. It had something to do with a
+filename being too long, and I gave up debugging after a while. In a
+fit of rage I started this blog post and experimenting with
+alternatives, which led me down a lot of rabbit holes.
 
-also tried `doveadm force-resync -u anarcat`
+## mailbox corruption
 
+Trying to sync over IMAP led to many problems like:
 
     nov 16 15:31:27 marcos dovecot[3621800]: imap(anarcat)<3630489><wAmSzO3QZtfAqAB1>: Error: Mailbox junk: Maildir filename has wrong W value, renamed the file from /home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495,W=2578:2,S to /home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495:2,S
     nov 16 15:31:27 marcos dovecot[3621800]: imap(anarcat)<3630489><wAmSzO3QZtfAqAB1>: Error: Mailbox junk: Deleting corrupted cache record uid=1582: UID 1582: Broken virtual size in mailbox junk: read(/home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495,W=2578:2,S): FETCH BODY[] got too little data: 2540 vs 2578
 
+and:
 
     nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: UID=19288: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288) (read reason=mail stream)
     nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: Deleting corrupted cache record uid=19288: UID 19288: Broken physical size in mailbox Sent: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288)
     nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: UID=19288: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288) (read reason=)
     nov 16 13:53:08 marcos dovecot[3520770]: imap-login: Panic: epoll_ctl(del, 7) failed: Bad file descriptor
 
-while ! mbsync anarcat; do sleep 1; done
+At least the first error was automatically healed by Dovecot. The
+problem is that the `FETCH` command then fails, so you need to
+constantly restart `mbsync` with a silly thing like:
+
+    while ! mbsync -a; do sleep 1; done
+
+The second one is much harder to fix, because dovecot does *not*
+self-heal that one. I wrote an extensive [fix script](https://gitlab.com/anarcat/scripts/-/blob/main/dovecot-fix-size-cache.py) for those two
+errors (because the above loop would have actually taken forever). I
+did read a lot on the [Dovecot documentation on the maildir format](https://doc.dovecot.org/admin_manual/mailbox_formats/maildir/).
+
+And no, [rebuilding the index files](https://dovecot.org/pipermail/dovecot/2019-June/116227.html) didn't work. Also tried
+`doveadm force-resync -u anarcat` which didn't do anything.
+
+In the end I also had to do:
 
-service dovecot stop ; find -name 'dovecot*' | while read f; do rm $f; done; service dovecot start
+    service dovecot stop ; find -name 'dovecot*' -delete; service dovecot start
 
+Which would have totally broken any existing clients.
 
 ## incoherences between maildir and IMAP
 

other ideas
diff --git a/blog/2021-11-16-mta-migration.md b/blog/2021-11-16-mta-migration.md
index 0e455bf2..402e029a 100644
--- a/blog/2021-11-16-mta-migration.md
+++ b/blog/2021-11-16-mta-migration.md
@@ -292,3 +292,12 @@ TODO: hook up in systemd, e.g. [this arch doc](https://wiki.archlinux.org/title/
 launched full sync, TODO: check how much time it took.
 
 [[!tag draft]]
+
+# other ideas
+
+considering:
+
+ * [interimap](https://guilhem.org/interimap/), presumably faster than dovecot sync and offlineimap
+ * [mail-sync](https://blog.hades.lkamp.de/mail-sync/)
+ * [doveadm-sync](https://wiki2.dovecot.org/Tools/Doveadm/Sync), if we're going to setup a local imap server
+   anyways, might as well get familiar with this

fix toc
diff --git a/blog/2021-11-16-mta-migration.md b/blog/2021-11-16-mta-migration.md
index 11fb2248..0e455bf2 100644
--- a/blog/2021-11-16-mta-migration.md
+++ b/blog/2021-11-16-mta-migration.md
@@ -1,5 +1,8 @@
+[[!toc levels=3]]
+
 TODO: link to [[previously|blog/2021-06-29-another-mail-crash]] and other
 
+# resurrecting my IMAP mail spool
 ## mailbox corruption
 
 TODO: expand on wtf was going on here.

more mailbox healing, now testing offlineimap
diff --git a/blog/2021-11-16-mta-migration.md b/blog/2021-11-16-mta-migration.md
index 354be5e9..11fb2248 100644
--- a/blog/2021-11-16-mta-migration.md
+++ b/blog/2021-11-16-mta-migration.md
@@ -1,6 +1,8 @@
+TODO: link to [[previously|blog/2021-06-29-another-mail-crash]] and other
 
+## mailbox corruption
 
-[[previously|blog/2021-06-29-another-mail-crash]].
+TODO: expand on wtf was going on here.
 
 [maildir format](https://doc.dovecot.org/admin_manual/mailbox_formats/maildir/)
 
@@ -10,7 +12,6 @@
 
 also tried `doveadm force-resync -u anarcat`
 
-full sync restarted at 19:57-0500
 
     nov 16 15:31:27 marcos dovecot[3621800]: imap(anarcat)<3630489><wAmSzO3QZtfAqAB1>: Error: Mailbox junk: Maildir filename has wrong W value, renamed the file from /home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495,W=2578:2,S to /home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495:2,S
     nov 16 15:31:27 marcos dovecot[3621800]: imap(anarcat)<3630489><wAmSzO3QZtfAqAB1>: Error: Mailbox junk: Deleting corrupted cache record uid=1582: UID 1582: Broken virtual size in mailbox junk: read(/home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495,W=2578:2,S): FETCH BODY[] got too little data: 2540 vs 2578
@@ -23,26 +24,268 @@ full sync restarted at 19:57-0500
 
 while ! mbsync anarcat; do sleep 1; done
 
-full sync:
+service dovecot stop ; find -name 'dovecot*' | while read f; do rm $f; done; service dovecot start
 
-"mbsync -a" took 56 mins 6 secs
 
-incremental is 5 seconds, pretty impressive:
+## incoherences between maildir and IMAP
 
-    1.30user 0.63system 0:04.94elapsed 39%CPU (0avgtext+0avgdata 29536maxresident)k
-    0inputs+116288outputs (0major+26349minor)pagefaults 0swaps
+Unfortunately, the first mbsync was incomplete as it's missing about
+15,000 mails:
 
+    anarcat@angela:~(main)$ find Maildir -type f | wc -l 
+    384836
+    anarcat@angela:~(main)$ find Maildir-mbsync/ -type f -a \! -name '.*' | wc -l 
+    369221
 
-service dovecot stop ; find -name 'dovecot*' | while read f; do rm $f; done; service dovecot start
+The analysis and repairs below show that mbsync is *probably* not at
+cause, but a full resync was restarted to verify that (TODO).
+
+It's actually 26 folders with different sizes, which can be found
+with:
+
+    for folder in * .[^.]* ; do 
+      printf "%s\t%d\n" $folder $(find "$folder" -type f -a \! -name '.*' | wc -l );
+    done
+
+The special `\! -name '.*'` bit is to ignore the mbsync metadata,
+which leaves `.uidvalidity` and `.mbsyncstate` in every folder. The
+difference is minor (about 200 files) but it makes looking at the
+differences much harder.
+
+Here is what the diff looks like:
+
+    --- Maildir-list	2021-11-17 20:42:36.504246752 -0500
+    +++ Maildir-mbsync-list	2021-11-17 20:18:07.731806601 -0500
+    @@ -6,16 +6,15 @@
+    [...]
+     .Archives	1
+     .Archives.2010	3553
+    -.Archives.2011	3583
+    -.Archives.2012	12593
+    +.Archives.2011	3582
+    +.Archives.2012	620
+     .Archives.2013	8576
+     .Archives.2014	11057
+    -.Archives.2015	8173
+    +.Archives.2015	8165
+     .Archives.2016	54
+     .band	34
+     .bitbuck	1
+    @@ -38,13 +37,12 @@
+     .couchsurfers	2
+    -cur	11285
+    +cur	11280
+     .current	130
+     .cv	2
+     .debbug	262
+    -.debian	37544
+    -drafts	1
+    -.Drafts	4
+    +.debian	37533
+    +.Drafts	2
+     .drone	241
+     .drupal	188
+     .drupal-devel	303
+    [...]
+
+It's a bit all over the place, but we can already notice some huge
+diffs, for example in the `Archives` folders. As it turns out, at
+least 12,000 of those missing mails were actually misfiled: instead of
+being in the `Maildir/.Archives.2012/cur` folder, they were *directly*
+in `Maildir/.Archives.2012/`. This is something that doesn't matter
+for smd (and possibly for notmuch?) but that definitely matters to
+Dovecot and therefore mbsync... After moving those files around, we
+get to a much more reasonable:
+
+    anarcat@angela:~(main)$ find Maildir-mbsync/  -type f -a \! -name '.*' | wc -l 
+    381196
+    anarcat@angela:~(main)$ find Maildir/  -type f -a \! -name '.*' | wc -l 
+    385053
+
+The problem with *those* 4,000 (still) missing mails is that they're
+much harder to track. Take, for example, `.Archives.2011`: it's a
+single file missing, out of 3,582. And the files are not identical:
+the checksums don't match after going through the IMAP transport, so
+we can't use a tool like [hashdeep](http://md5deep.sourceforge.net/) to compare the trees and find
+why that one file is missing.
+
+One big chunk of the 4000, however, is a special folder called
+`register` in my spool, which I was syncing separately. That actually
+covers 3,700 of those messages, so I actually have a more modest 300
+messages to figure out. After syncing *those* messages, I end up with
+the measly little:
+
+    anarcat@angela:~(main)$ find Maildir-mbsync/  -type f -a \! -name '.*' | wc -l 
+    384900
+    anarcat@angela:~(main)$ find Maildir/  -type f -a \! -name '.*' | wc -l 
+    385059
+
+Argh. still 160 mails out of sync. After *more* digging, I have found
+131 mails in the `tmp/` directories of the *client*'s
+mailspool. Mysterious! On the server side, it's even *more* files, and
+*not* the same ones. Possible that those were mails that were left
+there during a failed delivery of some sort, during a power failure or
+some sort of crash? Who knows.
+
+The first thing to do with those is to cleanup a bunch of empty files
+(21 on angela):
+
+    find .[^.]*/tmp -type f -empty -delete
+
+As *that* turns out, they are *all* duplicates, in the sense that
+notmuch can easily find a copy of files with the same message ID in
+its database. In other words, this hairy command returns nothing
+
+    find .[^.]*/tmp -type f | while read path; do 
+      grep ^Message-ID "$path";
+    done | sed 's/Message-ID: //;s/[<>]//g' | while read msgid ; do
+      notmuch search --output=files id:$msgid ;
+    done | grep tmp
+
+Well, that was actually pretty naive because `notmuch search` will
+just return nothing if the message is not found. This is the actual
+correct command:
+
+    find .[^.]*/tmp -type f | while read path; do
+      msgid=$(grep -m 1  -i ^message-id "$path" | sed 's/Message-ID: //i;s/[<>]//g');
+      if notmuch count --exclude=false  "id:$msgid" | grep -q 0; then
+        echo "$path <$msgid> not in notmuch" ;
+      fi;
+    done
+
+That actually returns empty. Or, to put it another way, this is safe:
+
+    find .[^.]*/tmp -type f -delete
+
+Poof! 314 mails cleaned on the server side. Interestingly, smd doesn't
+pick up on those changes *at all* and still sees files in `tmp/`
+directories on the client side, so we need to operate the same twisted
+logic there. After cleaning that on the client, we get:
+
+    anarcat@angela:~(main)$ find Maildir/  -type f -a \! -name '.*' | wc -l 
+    384928
+    anarcat@angela:~(main)$ find Maildir-mbsync/  -type f -a \! -name '.*' | wc -l 
+    384901
+
+Ha! 27 mails difference. Those are the really sticky ones, the ones
+that are unclear. I will restart a new full sync from scratch and see
+what's up with that. The great thing is that only takes an hour! TODO
+
+# mbsync tests
+
+## complex configuration
+
+I set this basic [mbsync](https://isync.sourceforge.io/) configuration:
+
+    SyncState *
+    Sync New ReNew Flags
+
+    IMAPAccount anarcat
+    Host imap.anarc.at
+    User anarcat
+    PassCmd "pass imap.anarc.at"
+    SSLType IMAPS
+    CertificateFile /etc/ssl/certs/ca-certificates.crt
+
+    IMAPStore anarcat-remote
+    Account anarcat
+
+    MaildirStore anarcat-local
+    # Maildir/top/sub/sub

(Diff truncated)
start working on my mta migration
diff --git a/blog/2021-11-16-mta-migration.md b/blog/2021-11-16-mta-migration.md
new file mode 100644
index 00000000..354be5e9
--- /dev/null
+++ b/blog/2021-11-16-mta-migration.md
@@ -0,0 +1,48 @@
+
+
+[[previously|blog/2021-06-29-another-mail-crash]].
+
+[maildir format](https://doc.dovecot.org/admin_manual/mailbox_formats/maildir/)
+
+[fix script](https://gitlab.com/anarcat/scripts/-/blob/main/dovecot-fix-size-cache.py)
+
+[rebuilding the index files](https://dovecot.org/pipermail/dovecot/2019-June/116227.html) didn't work
+
+also tried `doveadm force-resync -u anarcat`
+
+full sync restarted at 19:57-0500
+
+    nov 16 15:31:27 marcos dovecot[3621800]: imap(anarcat)<3630489><wAmSzO3QZtfAqAB1>: Error: Mailbox junk: Maildir filename has wrong W value, renamed the file from /home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495,W=2578:2,S to /home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495:2,S
+    nov 16 15:31:27 marcos dovecot[3621800]: imap(anarcat)<3630489><wAmSzO3QZtfAqAB1>: Error: Mailbox junk: Deleting corrupted cache record uid=1582: UID 1582: Broken virtual size in mailbox junk: read(/home/anarcat/Maildir/.junk/cur/1454623938.M101164P22216.marcos,S=2495,W=2578:2,S): FETCH BODY[] got too little data: 2540 vs 2578
+
+
+    nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: UID=19288: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288) (read reason=mail stream)
+    nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: Deleting corrupted cache record uid=19288: UID 19288: Broken physical size in mailbox Sent: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288)
+    nov 16 13:53:08 marcos dovecot[3520770]: imap(anarcat)<3594402><M5JHb+zQ3NLAqAB1>: Error: Mailbox Sent: UID=19288: read(/home/anarcat/Maildir/.Sent/cur/1224790447.M898726P9811V000000000000FE06I00794FB1_0.marvin,S=2588:2,S) failed: Cached message size larger than expected (2588 > 2482, box=Sent, UID=19288) (read reason=)
+    nov 16 13:53:08 marcos dovecot[3520770]: imap-login: Panic: epoll_ctl(del, 7) failed: Bad file descriptor
+
+while ! mbsync anarcat; do sleep 1; done
+
+full sync:
+
+"mbsync -a" took 56 mins 6 secs
+
+incremental is 5 seconds, pretty impressive:
+
+    1.30user 0.63system 0:04.94elapsed 39%CPU (0avgtext+0avgdata 29536maxresident)k
+    0inputs+116288outputs (0major+26349minor)pagefaults 0swaps
+
+
+service dovecot stop ; find -name 'dovecot*' | while read f; do rm $f; done; service dovecot start
+
+comparing folders:
+
+for folder in * .[^.]* ; do  printf "%d\t%s\n" $(find "$folder" -type f | wc -l ) $folder; done
+
+
+anarcat@angela:~(main)$ find Maildir -type f | wc -l 
+384836
+anarcat@angela:~(main)$ find Maildir-mbsync/ -type f | wc -l 
+369406
+
+[[!tag draft]]

more providers
diff --git a/services/backup.mdwn b/services/backup.mdwn
index 3b5806a5..492d5161 100644
--- a/services/backup.mdwn
+++ b/services/backup.mdwn
@@ -286,6 +286,11 @@ Backups:
 
 * [Backblaze](https://www.backblaze.com/): 5USD/mth/machine; "cloud storage" at ~5$/TB/mth
 
+Colo (mostly things that came out of the [GitLab colo plan](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/727):
+
+* [NYI](https://www.nyi.net/)
+* [Softlayer](https://gitlab.com/gitlab-com/operations/-/issues/14) (AKA IBM)
+
 See also [Goerzen's list](https://changelog.complete.org/archives/10265-roundup-of-unique-data-storage-hosting-options).
 
 Offsite procedures

curie hardware alternative
diff --git a/hardware/curie.mdwn b/hardware/curie.mdwn
index 7a647816..b3bc5044 100644
--- a/hardware/curie.mdwn
+++ b/hardware/curie.mdwn
@@ -181,6 +181,12 @@ much larger.
 
 To investigate: see the [Brix](https://www.gigabyte.com/us/Mini-PcBarebone) and [Qotom](https://www.qotom.net/) mini-PCs.
 
+### Tuxedo
+
+<https://www.gamingonlinux.com/2021/11/the-tuxedo-nano-pro-is-a-powerhouse-in-a-tiny-box>
+
+AMD thingies. Promising, but no sd-card reader. Possibly not a deal breaker.
+
 ### Purism
 
 Purism [announced their own mini-PC as well](https://puri.sm/posts/announcing-the-purism-librem-mini/), although I kind of

clarify another piece, from fr translation
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index d721b1d4..44667f72 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -259,7 +259,7 @@ mirroring the infamous "All men are created equal" claim of the US
 declaration.)
 
 As the Wall Street Journal's (WSJ) [Facebook files][] later shown,
-both of those have serious limitations inside Facebook. There are
+both of those "contracts" have serious limitations inside Facebook. There are
 [VIPs who systematically bypass moderation systems][] including
 [fascists][] and [rapists][]. Drug cartels and human traffickers
 [thrive on the platform][]. Even when Zuckerberg himself tried to

some language tweaks to the original after reviewing a translation
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index 619006ae..d721b1d4 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -180,8 +180,8 @@ before.)
 
 The point is: all those companies have gigantic data centers and
 intercontinental cables. And those are definitely prioritizing the
-western world, the heart of the empire. To take an example, [Google's
-latest 3,900 mile undersea cable][] does not connect Argentina to
+western world, the heart of the empire. Take for example [Google's
+latest 3,900 mile undersea cable][]: it does not connect Argentina to
 South Africa or New Zealand, it connects the US to UK and
 Spain. Hardly a revolutionary prospect.
 
@@ -454,9 +454,9 @@ The Declaration actually ends like this, a quote which I have in my
 That is still inspiring to me. But if we want to make "cyberspace"
 more humane, we need to decolonize it. Work on cyberpeace instead of
 cyberwar. Establish clear code of conduct, discuss ethics, and
-question your own biases and culture. For me the first step in
-decolonizing my own mind is writing this article. [Breaking up][]
-[tech monopolies][] might be an important step, but it won't be
+question your own privileges, biases, and culture. For me the first
+step in decolonizing my own mind is writing this article. [Breaking
+up][] [tech monopolies][] might be an important step, but it won't be
 enough: we have to do a culture shift as well, and that's the hard
 part.
 
@@ -502,7 +502,7 @@ nations, in some of the last major [First Nations Wars][].
 There is another article that almost has the same title as this one:
 [Facebook and the New Colonialism][]. (Interestingly, the `<title>`
 tag on the article is actually "Facebook the Colonial Empire" which I
-also find interesting.) The article is worth reading in full, but I
+also find appropriate.) The article is worth reading in full, but I
 loved this quote so much that I couldn't resist reproducing it here:
 
 [Facebook and the New Colonialism]: https://www.theatlantic.com/technology/archive/2016/02/facebook-and-the-new-colonialism/462393/

make links refs to make it easier to reuse in translation
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index f5fe2391..619006ae 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -4,10 +4,13 @@
 
 I grew up with the Internet and its ethics and politics have always
 been important in my life. But I have also been involved at other
-levels, [against police brutality](https://cobp.resist.ca/), for [Food, Not Bombs](https://foodnotbombs.net/),
-[worker autonomy][koumbit], [software freedom](https://www.debian.org/), etc. For a long time,
+levels, [against police brutality][], for [Food, Not Bombs][],
+[worker autonomy][koumbit], [software freedom][], etc. For a long time,
 that all seemed coherent.
 
+[software freedom]: https://www.debian.org/
+[Food, Not Bombs]: https://foodnotbombs.net/
+[against police brutality]: https://cobp.resist.ca/
 [koumbit]: https://www.koumbit.org/
 [declaration of independence of cyberspace]: https://www.eff.org/cyberspace-independence
 
@@ -24,10 +27,14 @@ from the start. Let me explain.
 
 # What is Neo-Colonialism?
 
-The term "[neo-colonialism](https://en.wikipedia.org/wiki/Neocolonialism)" was coined by [Kwame Nkrumah](https://en.wikipedia.org/wiki/Kwame_Nkrumah),
-first president of [Ghana](https://en.wikipedia.org/wiki/Ghana). In *Neo-Colonialism, the Last Stage of
+The term "[neo-colonialism][]" was coined by [Kwame Nkrumah][],
+first president of [Ghana][]. In *Neo-Colonialism, the Last Stage of
 Imperialism* (1965), he wrote:
 
+[Ghana]: https://en.wikipedia.org/wiki/Ghana
+[Kwame Nkrumah]: https://en.wikipedia.org/wiki/Kwame_Nkrumah
+[neo-colonialism]: https://en.wikipedia.org/wiki/Neocolonialism
+
 > In place of colonialism, as the main instrument of imperialism, we
 > have today neo-colonialism ... [which] like colonialism, is an
 > attempt to export the social conflicts of the capitalist
@@ -39,11 +46,13 @@ Imperialism* (1965), he wrote:
 > increases, rather than decreases, the gap between the rich and the
 > poor countries of the world.
 
-So basically, if [colonialism](https://en.wikipedia.org/wiki/Colonialism) is Europeans bringing genocide, war,
+So basically, if [colonialism][] is Europeans bringing genocide, war,
 and its religion to the Africa, Asia, and the Americas,
 neo-colonialism is the Americans (note the "n") bringing capitalism to
 the world.
 
+[colonialism]: https://en.wikipedia.org/wiki/Colonialism
+
 Before we see how this applies to the Internet, we must therefore make
 a detour into US history. This matters, because anyone would be
 hard-pressed to decouple neo-colonialism from the empire under which
@@ -51,13 +60,16 @@ it evolves, and here we can only name the United States of America.
 
 # US Declaration of Independence
 
-Let's start with the [United States declaration of independence](https://en.wikipedia.org/wiki/United_States_Declaration_of_Independence)
+Let's start with the [United States declaration of independence][]
 (1776). Many Americans may roll their eyes at this, possibly because
-that declaration is not actually part of the [US constitution](https://en.wikipedia.org/wiki/Constitution_of_the_United_States) and
+that declaration is not actually part of the [US constitution][] and
 therefore may have questionable legal standing. Still, it was
 obviously a driving philosophical force in the founding of the
 nation. As its author, Thomas Jefferson, stated:
 
+[US constitution]: https://en.wikipedia.org/wiki/Constitution_of_the_United_States
+[United States declaration of independence]: https://en.wikipedia.org/wiki/United_States_Declaration_of_Independence
+
 > it was intended to be an expression of the American mind, and to
 > give to that expression the proper tone and spirit called for by the
 > occasion
@@ -74,27 +86,36 @@ sense that the above quote has been called an:
 
 > "immortal declaration", and "perhaps [the] single phrase" of the
 > American Revolutionary period with the greatest "continuing
-> importance." ([Wikipedia](https://en.wikipedia.org/wiki/All_men_are_created_equal))
+> importance." ([Wikipedia][])
+
+[Wikipedia]: https://en.wikipedia.org/wiki/All_men_are_created_equal
 
 Let's read that "immortal declaration" again: "all *men* are created
 equal". "Men", in that context, is limited to a certain number of
 people, namely "[property-owning or tax-paying white males, or about
-6% of the population](https://en.wikipedia.org/wiki/Voting_rights_in_the_United_States#Milestones_of_national_franchise_changes)". Back when this was written, women didn't
+6% of the population][]". Back when this was written, women didn't
 have the right to vote, and slavery was legal. Jefferson himself owned
 hundreds of slaves.
 
-The declaration was aimed at the [King](https://en.wikipedia.org/wiki/George_III_of_the_United_Kingdom) and was a [list of
-grievances](https://en.wikipedia.org/wiki/Grievances_of_the_United_States_Declaration_of_Independence). A concern of the colonists was that the King:
+[property-owning or tax-paying white males, or about 6% of the population]: https://en.wikipedia.org/wiki/Voting_rights_in_the_United_States#Milestones_of_national_franchise_changes
+
+The declaration was aimed at the [King][] and was a [list of
+grievances][]. A concern of the colonists was that the King:
+
+[list of grievances]: https://en.wikipedia.org/wiki/Grievances_of_the_United_States_Declaration_of_Independence
+[King]: https://en.wikipedia.org/wiki/George_III_of_the_United_Kingdom
 
 > has excited domestic insurrections amongst us, and has endeavoured
 > to bring on the inhabitants of our frontiers, the merciless Indian
 > Savages whose known rule of warfare, is an undistinguished
 > destruction of all ages, sexes and conditions.
 
-This is a clear mark of the [frontier myth](https://en.wikipedia.org/wiki/Frontier_myth) which paved the way for
+This is a clear mark of the [frontier myth][] which paved the way for
 the US to exterminate and colonize the territory some now call the
 United States of America.
 
+[frontier myth]: https://en.wikipedia.org/wiki/Frontier_myth
+
 The declaration of independence is obviously a colonial document,
 having being written by colonists. None of this is particularly
 surprising, historically, but I figured it serves as a good reminder
@@ -102,42 +123,57 @@ of where the Internet is coming from, since it was born in the US.
 
 # A Declaration of the Independence of Cyberspace
 
-Two hundred and twenty years later, in 1996, [John Perry Barlow](https://en.wikipedia.org/wiki/John_Perry_Barlow_)
+Two hundred and twenty years later, in 1996, [John Perry Barlow][]
 wrote a [declaration of independence of cyberspace][declaration of independence of cyberspace].  At this
-point, ([almost](https://en.wikipedia.org/wiki/Voting_rights_in_the_United_States)) everyone has a right to vote (including women),
+point, ([almost][]) everyone has a right to vote (including women),
 slavery was abolished (although [some argue it still exists in the
-form of the prison system](https://en.wikipedia.org/wiki/Angela_Davis#Political_activism_and_speeches)); the US has made tremendous
+form of the prison system][]); the US has made tremendous
 progress. Surely this text will have aged better than the previous
 declaration it is obviously derived from. Let's see how it reads today
 and how it maps to how the Internet is actually built now.
 
+[some argue it still exists in the form of the prison system]: https://en.wikipedia.org/wiki/Angela_Davis#Political_activism_and_speeches
+[almost]: https://en.wikipedia.org/wiki/Voting_rights_in_the_United_States
+[John Perry Barlow]: https://en.wikipedia.org/wiki/John_Perry_Barlow_
+
 # Borders of Independence
 
 One of the key ideas that Barlow brings up is that "*cyberspace does
 not lie within your borders*". In that sense, cyberspace is the [final
-frontier](https://en.wikipedia.org/wiki/Final_Frontier): having failed to colonize the moon, Americans turn
+frontier][]: having failed to colonize the moon, Americans turn
 inwards, deeper into technology, but still in the frontier
 ideology. And indeed, Barlow is one of the co-founder of the
-Electronic *Frontier* Foundation (the beloved [EFF](https://en.wikipedia.org/wiki/Electronic_Frontier_Foundation)), founded six
+Electronic *Frontier* Foundation (the beloved [EFF][]), founded six
 years prior.
 
-But there are other problems with this idea. As [Wikipedia quotes](https://en.wikipedia.org/wiki/A_Declaration_of_the_Independence_of_Cyberspace#Critical_response):
+[EFF]: https://en.wikipedia.org/wiki/Electronic_Frontier_Foundation
+[final frontier]: https://en.wikipedia.org/wiki/Final_Frontier
+
+But there are other problems with this idea. As [Wikipedia quotes][]:
+
+[Wikipedia quotes]: https://en.wikipedia.org/wiki/A_Declaration_of_the_Independence_of_Cyberspace#Critical_response
 
 > The declaration has been criticized for internal
-> inconsistencies.[[9](https://web.archive.org/web/20161105174638/http://ieet.org/index.php/IEET/more/evans0220)] The declaration's assertion that
+> inconsistencies.[[9][]] The declaration's assertion that
 > 'cyberspace' is a place removed from the physical world has also
 > been challenged by people who point to the fact that the Internet is
-> always linked to its underlying geography.[[10](https://doi.org/10.1111%2Fgeoj.12009<)]
+> always linked to its underlying geography.[[10][]]
+
+[10]: https://doi.org/10.1111%2Fgeoj.12009
+[9]: https://web.archive.org/web/20161105174638/http://ieet.org/index.php/IEET/more/evans0220
 
 And indeed, the Internet is definitely a physical object. First
 controlled and severely restricted by "telcos" like AT&T, it was
 somewhat "liberated" from that monopoly in 1982 when an [anti-trust
-lawsuit](https://en.wikipedia.org/wiki/United_States_v._AT%26T) [broke up the monopoly](https://en.wikipedia.org/wiki/Breakup_of_the_Bell_System), a key historical event that,
+lawsuit][] [broke up the monopoly][], a key historical event that,
 one could argue, made the Internet possible.
 
+[broke up the monopoly]: https://en.wikipedia.org/wiki/Breakup_of_the_Bell_System
+[anti-trust lawsuit]: https://en.wikipedia.org/wiki/United_States_v._AT%26T
+
 (From there on, "backbone" providers could start competing and emerge,
 and eventually coalesce into new monopolies: Google has a monopoly on
-search and advertistement, Facebook on communications for a few
+search and advertisement, Facebook on communications for a few
 generations, Amazon on storage and computing, Microsoft on hardware,
 etc. Even AT&T is now pretty much as consolidated as it was
 before.)
@@ -145,10 +181,12 @@ before.)
 The point is: all those companies have gigantic data centers and
 intercontinental cables. And those are definitely prioritizing the
 western world, the heart of the empire. To take an example, [Google's
-latest 3,900 mile undersea cable](https://www.cnet.com/tech/google-finishes-3900-mile-subsea-cable-connecting-us-to-uk-and-spain/) does not connect Argentina to
+latest 3,900 mile undersea cable][] does not connect Argentina to
 South Africa or New Zealand, it connects the US to UK and
 Spain. Hardly a revolutionary prospect.
 
+[Google's latest 3,900 mile undersea cable]: https://www.cnet.com/tech/google-finishes-3900-mile-subsea-cable-connecting-us-to-uk-and-spain/
+
 # Private Internet
 
 But back to the Declaration:
@@ -165,39 +203,50 @@ most of the Internet is now privately owned and operated.
 I must admit that, as an anarchist, I loved that sentence when I read
 it. I was rooting for "us", the underdogs, the revolutionaries. And,
 in a way, I still do: I am on the board of [Koumbit][] and work for a
-[non-profit](https://www.torproject.org/) that has pivoted towards censorship and surveillance

(Diff truncated)
thanks for the clarification
diff --git a/blog/2021-11-04-contextmanager-gotcha/comment_4_b996ca4f74f83729a1e65a7b080c46c5._comment b/blog/2021-11-04-contextmanager-gotcha/comment_4_b996ca4f74f83729a1e65a7b080c46c5._comment
new file mode 100644
index 00000000..8e874d7b
--- /dev/null
+++ b/blog/2021-11-04-contextmanager-gotcha/comment_4_b996ca4f74f83729a1e65a7b080c46c5._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="anarcat"
+ subject="""comment 4"""
+ date="2021-11-07T22:23:19Z"
+ content="""
+See this is exactly why this is a horrible gotcha and, to a certain extent, an API failure. Even looking at the docs, the two of us, we can't quite make up our minds as to what exactly is going on, because it's kind of a tangled mess.
+
+I think you're right here: the contextmanager object doesn't change the try/except/finally semantics and `return` in the `finally` discards the exception.
+
+But somehow because this is inside a contextmanager, I am led to imagine things act differently. I think part of the problem here is that the contextmanager docs do not explicitly state what ends up in the `__exit__()` code. It just says that you don't have to explicitly make it.
+
+But yeah, you're right: the return value doesn't matter.
+"""]]

approve comment
diff --git a/blog/2021-11-04-contextmanager-gotcha/comment_1_87b500dc54d5695e2ee178834cc56a0b._comment b/blog/2021-11-04-contextmanager-gotcha/comment_1_87b500dc54d5695e2ee178834cc56a0b._comment
new file mode 100644
index 00000000..28e4caa2
--- /dev/null
+++ b/blog/2021-11-04-contextmanager-gotcha/comment_1_87b500dc54d5695e2ee178834cc56a0b._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ ip="84.119.13.157"
+ claimedauthor="stbuehler"
+ subject="it's not about __exit__"
+ date="2021-11-07T10:39:01Z"
+ content="""
+Actually the returned value doesn't matter; I don't think `contextmanager` uses it at all (it uses its own exception suppression logic).
+
+What actually suppresses the exception is this (from [8.4. The try statement](https://docs.python.org/3/reference/compound_stmts.html#the-try-statement)):
+> If the finally clause executes a return, break or continue statement, the saved exception is discarded:
+
+And this is why at least on my system nothing changes when I use `return False` or just `return` (and put the print on the line before).
+"""]]

response
diff --git a/blog/2021-11-04-contextmanager-gotcha/comment_2_1cc461405b70e2c9e4b491fb2d7b8616._comment b/blog/2021-11-04-contextmanager-gotcha/comment_2_1cc461405b70e2c9e4b491fb2d7b8616._comment
new file mode 100644
index 00000000..c78ffc46
--- /dev/null
+++ b/blog/2021-11-04-contextmanager-gotcha/comment_2_1cc461405b70e2c9e4b491fb2d7b8616._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="anarcat"
+ subject="""comment 2"""
+ date="2021-11-05T17:59:05Z"
+ content="""
+Frankly, I don't remember. The point is not really the return value of `print` here, the point is the `return`. I could have `return "kumbaya"` and it would have worked, and a plain `return` and it wouldn't have, the trick with `return print()` is that it's not obvious what the return value is for a newbie (it's `None`, of course, which is the whole point here).
+"""]]

approve comment
diff --git a/blog/2021-11-04-contextmanager-gotcha/comment_1_8e2688e78e1b4ef5d29d74025b8e1da4._comment b/blog/2021-11-04-contextmanager-gotcha/comment_1_8e2688e78e1b4ef5d29d74025b8e1da4._comment
new file mode 100644
index 00000000..f197ee52
--- /dev/null
+++ b/blog/2021-11-04-contextmanager-gotcha/comment_1_8e2688e78e1b4ef5d29d74025b8e1da4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ ip="146.112.53.118"
+ claimedauthor="glacierre"
+ subject="return print??"
+ date="2021-11-05T10:59:19Z"
+ content="""
+I knew about the context manager behavior, what I don't know how to make heads of tails of is what do you expect from returning print(\"...\")!
+"""]]

fix tags
diff --git a/blog/2021-11-04-contextmanager-gotcha.md b/blog/2021-11-04-contextmanager-gotcha.md
index b40fb715..a5145303 100644
--- a/blog/2021-11-04-contextmanager-gotcha.md
+++ b/blog/2021-11-04-contextmanager-gotcha.md
@@ -104,4 +104,4 @@ to make that mistake...
 Credits to the [Python tips book](https://book.pythontips.com/en/latest/context_managers.html#implementing-a-context-manager-as-a-generator) for teaching me about that trick
 in the first place.
 
-[[!tags debian-planet python-planet python programming]]
+[[!tag debian-planet python-planet python programming]]

a contextmanager gotcha
diff --git a/blog/2021-11-04-contextmanager-gotcha.md b/blog/2021-11-04-contextmanager-gotcha.md
new file mode 100644
index 00000000..b40fb715
--- /dev/null
+++ b/blog/2021-11-04-contextmanager-gotcha.md
@@ -0,0 +1,107 @@
+[[!meta title="A Python contextmanager gotcha"]]
+
+Dear lazy web...
+
+I've had this code sitting around as a `wtf.py` for a while. I've been
+meaning to understand what's going on and write a blog post about it
+for a while, but I'm lacking the time. Now that I have a few minutes,
+I actually sat down to look at it and I think I figured it out:
+
+[[!format python """
+from contextlib import contextmanager
+
+
+@contextmanager
+def bad():
+    print('in the context manager')
+    try:
+        print("yielding value")
+        yield 'value'
+    finally:
+        return print('cleaning up')
+
+
+@contextmanager
+def good():
+    print('in the context manager')
+    try:
+        print("yielding value")
+        yield 'value'
+    finally:
+        print('cleaning up')
+
+
+with bad() as v:
+    print('got v = %s' % v)
+    raise Exception('exception not raised!')  # SILENCED!
+
+print("this code is reached")
+with good() as v:
+    print('got v = %s' % v)
+    raise Exception('expection normally raised')
+
+print("NOT REACHED (expected)")
+"""]]
+
+For those, like me, who need a walkthrough, here's what the above
+does:
+
+ 1. define a `bad` context manager (the things you use with [with
+    statements](https://docs.python.org/3/reference/compound_stmts.html#with)) with [contextlib.contextmanager](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager)) which:
+    
+    1. prints a debug statement
+    2. return a value
+    3. then returns and prints a debug statement
+
+ 2. define a `good` context manager in much the same way, except it
+    doesn't return, it just prints statement
+
+ 3. use the `bad` context manager to show how it bypasses an exception
+
+ 4. use the good context manager to show how it correctly raises the
+    exception
+
+The output of this code (in Debian 11 bullseye, Python 3.9.2) is:
+
+    in the context manager
+    yielding value
+    got v = value
+    cleaning up
+    this code is reached
+    in the context manager
+    yielding value
+    got v = value
+    cleaning up
+    Traceback (most recent call last):
+      File "/home/anarcat/wikis/anarc.at/wtf.py", line 31, in <module>
+        raise Exception('expection normally raised')
+    Exception: expection normally raised
+
+What is surprising to me, with this code, is not only does the
+exception not get raised, but also the `return` statement doesn't seem
+to actually execute, or at least not in the parent scope: if it would,
+`this code is reached` wouldn't be printed and the rest of the code
+wouldn't run either.
+
+So what's going on here? Now I know that I should be careful with
+`return` in my context manager, but why? And why is it silencing the
+exception?
+
+The reason why it's being silenced is this little chunk in the `with`
+documentation:
+
+> If the suite was exited due to an exception, and the return value
+> from the __exit__() method was false, the exception is reraised. If
+> the return value was true, the exception is suppressed, and
+> execution continues with the statement following the with
+> statement.
+
+This feels a little too magic. If you write a context manager with
+`__exit__()`, you're kind of forced to lookup again what that API
+is. But the `contextmanager` decorator hides that away and it's easy
+to make that mistake...
+
+Credits to the [Python tips book](https://book.pythontips.com/en/latest/context_managers.html#implementing-a-context-manager-as-a-generator) for teaching me about that trick
+in the first place.
+
+[[!tags debian-planet python-planet python programming]]

document my actual keyboards
i had those images sitting around and didn't know what to do with
them. now i kind of know.
diff --git a/hardware/keyboard.mdwn b/hardware/keyboard.mdwn
index f74a54f2..77079444 100644
--- a/hardware/keyboard.mdwn
+++ b/hardware/keyboard.mdwn
@@ -2,10 +2,52 @@ I [type so much](http://anarcat.koumbit.org/2010-03-22-working-too-much-computer
 
 [[!toc levels=2]]
 
-Update: I ended up buying a Rosewill RK-9000 with, I believe, Cherry
-MX blue keys. That turned out to be too noisy, even with my roommates
-being *in the next room*, so I do not use the keyboard except as a
-spare now (!).
+# Actual keyboards
+
+## Rosewill
+
+I first bought a Rosewill RK-9000 with, I believe, Cherry MX blue
+keys. That turned out to be too noisy, even with my roommates being
+*in the next room*, so I do not use the keyboard except as a spare
+now.
+
+## WASD
+
+I have a [Custom 87-key mechanical keyboard](https://www.wasdkeyboards.com/index.php/products/mechanical-keyboard/wasd-v3-87-key-custom-mechanical-keyboard.html) with cherry MX "brown"
+switches and a custom coloring and labeling layout. I first ordered it
+with cherry MX "red" by mistake, and WASD were nice enough to accept a
+return, but I had to pay shipping costs.
+
+The keys worn out pretty fast, which is kind of sad, otherwise it's
+absolutely gorgeous:
+
+<figure> <img src="IMG_0560.jpg" alt="A photo of the keyboard which
+has mostly white keys, except control keys in grey, enter and escape
+in red. Key labels are in the middle of keys which is unusual." />
+<figcaption>My fancy keyboard with a key extractor on top. The escape
+key has the <a
+href="https://archive.iww.org/history/icons/black_cat/">IWW black
+cat</a> on the escape key, and an <a
+href="https://0xacab.org/anarcat/apt-get-install-anarchism">apt-get
+install anarchism swirl</a> on the meta keys </figcaption> </figure>
+
+It looks pretty much like the rendering they give you in their online
+design tool:
+
+<figure>
+<img src="wasd-final2.PNG" alt="A rendering of the keyboard layout" />
+</figure>
+
+I have ordered [reprints](https://www.wasdkeyboards.com/index.php/products/printed-keycap-singles/reprinted-key.html) of those worn-out keys, on the upside,
+but it's still a bit of a luxury, especially because of the design
+with the key labels in the middle. (There's a reason why that design
+has gone away, and that's because the labels wear out faster!)
+
+I have *also* ordered a less exotic [WASD V3 87-Key Doubleshot PBT
+Black/Slate Mechanical Keyboard](https://www.wasdkeyboards.com/index.php/products/mechanical-keyboard/wasd-87-key-doubleshot-pbt-black-slate-mechanical-keyboard.html), because they keys wear out much
+less, and it's still really pretty. The V3 is kind of nice because you
+can reprogram the LED, although it's really complicated how you do
+that. I made caps lock red and scroll lock green.
 
 # Requirements
 
@@ -90,19 +132,6 @@ everything.
    > Algorithm: Time base=1ms, Fixed time =4ms, continuous 3 times with same
    > result, KEY state can be determined.
 
-Update:
-
- * I ordered a [Custom 87-key mechanical keyboard](https://www.wasdkeyboards.com/index.php/products/mechanical-keyboard/wasd-v3-87-key-custom-mechanical-keyboard.html) with cherry MX
-   "brown" switches and a custom coloring and labeling layout
- * the keys worn out pretty fast, which is kind of sad, otherwise it's
-   absolutely gorgeous
- * I could order [reprints](https://www.wasdkeyboards.com/index.php/products/printed-keycap-singles/reprinted-key.html) of those worn-out keys, on the upside
- * i first ordered it with cherry MX "red" by mistake, and WASD were
-   nice enough to accept a return, but I had to pay shipping costs
- * I would probably order a [WASD V3 87-Key Doubleshot PBT Black/Slate
-   Mechanical Keyboard](https://www.wasdkeyboards.com/index.php/products/mechanical-keyboard/wasd-87-key-doubleshot-pbt-black-slate-mechanical-keyboard.html) next time, because they keys wear out much
-   less, and it's still really pretty
-
 ## CODE
 
 The [CODE keyboard](http://codekeyboards.com/) is also made by WASD but has special specs.
diff --git a/hardware/keyboard/IMG_0560.jpg b/hardware/keyboard/IMG_0560.jpg
new file mode 100644
index 00000000..c831ad52
Binary files /dev/null and b/hardware/keyboard/IMG_0560.jpg differ
diff --git a/hardware/keyboard/wasd-final.PNG b/hardware/keyboard/wasd-final.PNG
new file mode 100644
index 00000000..0a593e1e
Binary files /dev/null and b/hardware/keyboard/wasd-final.PNG differ
diff --git a/hardware/keyboard/wasd-final2.PNG b/hardware/keyboard/wasd-final2.PNG
new file mode 100644
index 00000000..b3f49056
Binary files /dev/null and b/hardware/keyboard/wasd-final2.PNG differ

force-link to pixel 4a blurb
diff --git a/hardware/phone.mdwn b/hardware/phone.mdwn
index 1d226c7d..ddeb3235 100644
--- a/hardware/phone.mdwn
+++ b/hardware/phone.mdwn
@@ -2,7 +2,7 @@ This section documents my experiments with cellular phone
 technology. I have more detailed guides and documentation on specific
 phones as well:
 
-[[!map pages="page(hardware/phone/*)"]]
+[[!map pages="page(hardware/phone/*) or page(blog/2021-01-13-new-phone)"]]
 
 **Table of contents**:
 

another server platform
diff --git a/hardware/server/marcos.mdwn b/hardware/server/marcos.mdwn
index d5731bf1..b0f57245 100644
--- a/hardware/server/marcos.mdwn
+++ b/hardware/server/marcos.mdwn
@@ -376,6 +376,12 @@ https://www.crowdsupply.com/traverse-technologies/ten64/updates/building-a-nas-w
 
 To investigate: see the [Brix](https://www.gigabyte.com/us/Mini-PcBarebone) and [Qotom](https://www.qotom.net/) mini-PCs.
 
+## Protectli
+
+getting out of scope, but:
+
+https://protectli.com/
+
 ## Other SoC boards
 
 There are many SoC boards that could be used to create a device from

zsh latency is a thing, apparently
diff --git a/blog/2018-05-04-terminal-emulators-2.mdwn b/blog/2018-05-04-terminal-emulators-2.mdwn
index b140e53a..7b6b9d04 100644
--- a/blog/2018-05-04-terminal-emulators-2.mdwn
+++ b/blog/2018-05-04-terminal-emulators-2.mdwn
@@ -321,4 +321,6 @@ mean more latency there:
 But it seems I would need an oscilloscope (and know how to use it!) to
 debug this. ;)
 
+Update 2: some people seem to care about [zsh latency](https://github.com/romkatv/zsh-bench) as well.
+
 [[!tag debian-planet lwn geek review terminals performance]]

more css frameworks
diff --git a/services/wiki.mdwn b/services/wiki.mdwn
index 9266fa38..f7d936f3 100644
--- a/services/wiki.mdwn
+++ b/services/wiki.mdwn
@@ -75,8 +75,19 @@ Here are some things I'm thinking of doing on the website:
      than 50% of the page size is CSS and JS (23% and 30% resp.). we
      don't need this framework to make a pretty site, and there are
      other much smaller frameworks, see for
-     example [pure.css][], [miligram][], [bulma][], [min][], 
-     [mini.css][], [skeleton][], [picnic][], [TufteCSS][] and [plenty][] [more][]
+     examples:
+     * [TufteCSS][]
+     * [bulma][]
+     * [miligram][]
+     * [marx][]
+     * [min][]
+     * [mini.css][]
+     * [picnic][]
+     * [pico.css][]
+     * [pure.css][]
+     * [skeleton][]
+     * [tailwind][]
+     * and [plenty][] [more][]
    * <del>ditch the Fira font</del> done - this greatly reduced the
      loading time
    * ditch JQuery - i'm not sure why it's used, but it certainly takes
@@ -101,6 +112,9 @@ Here are some things I'm thinking of doing on the website:
  * theming improvements:
    * [followup on the font changes](/blog/2020-03-10-font-changes)
 
+[pico.css]: https://picocss.com/
+[tailwind]: https://tailwindcss.com/
+[marx]: https://mblode.github.io/marx/
 [TufteCSS]: https://edwardtufte.github.io/tufte-css/
 [controlpanel]: http://anarc.at/ikiwiki.cgi?do=controlpanel
 [more]: http://codecondo.com/minimal-css-frameworks-grid-systems/

add teracube
diff --git a/hardware/phone.mdwn b/hardware/phone.mdwn
index 0009ba14..1d226c7d 100644
--- a/hardware/phone.mdwn
+++ b/hardware/phone.mdwn
@@ -534,6 +534,12 @@ Puzzlephone
 
 Similarly, there's a [pretty homepage](http://www.puzzlephone.com/) while we wait for something to happen also.
 
+# Teracube
+
+<https://myteracube.com/>
+
+4 years support, possibly greenwashing. 200USD.
+
 Current phone
 =============
 

fix links to buster manpage
diff --git a/services/upgrades/bullseye.mdwn b/services/upgrades/bullseye.mdwn
index 6192fd1e..c7b9bdff 100644
--- a/services/upgrades/bullseye.mdwn
+++ b/services/upgrades/bullseye.mdwn
@@ -154,7 +154,7 @@ noticed.
  * [password hashes have changed](https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.en.html#pam-default-password) to [yescrypt](https://www.openwall.com/yescrypt/) (recognizable
    from its `$y$` prefix), a major change from the previous default,
    SHA-512 (recognizable from its `$6$` prefix), see also
-   [crypt(5)](https://manpages.debian.org/crypt.5) (in bullseye), [crypt(3)](https://manpages.debian.org/crypt.3) (in buster), and
+   [crypt(5)](https://manpages.debian.org/crypt.5) (in bullseye), [crypt(3)](https://manpages.debian.org/buster/manpages-dev/crypt.3.en.html) (in buster), and
    `mkpasswd -m help` for a list of supported hashes on whatever
 
 There is a more [exhaustive review of server-level changes from

bezos is not CEO
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index a248cdfa..f5fe2391 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -176,8 +176,11 @@ traditional political entities supposedly representing the people, or
 even its users. The situation is actually *worse* than when the US was
 founded (e.g. "6% of the population can vote"), because the owners of the
 tech giants are only a handful of people who can override any
-decision. There's only one Amazon CEO, he's called Jeff Bezos, and he
-has total control.
+decision. There's only one Amazon CEO, he's called [Jeff Bezos](https://en.wikipedia.org/wiki/Jeff_Bezos), and he
+has total control. (Update: Bezos actually ceded the CEO role to [Andy
+Jassy](https://en.wikipedia.org/wiki/Andy_Jassy), AWS and Amazon music founder, while remaining [executive
+chairman](https://en.wikipedia.org/wiki/Chairperson#Executive_chairperson). I would argue that, as the founder and the richest man
+on earth, he still has strong control over Amazon.)
 
 # Social Contract
 

Europe didn't bring colonialism only to the Americas
Thanks h0lger!
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index 5468b5c0..a248cdfa 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -40,8 +40,9 @@ Imperialism* (1965), he wrote:
 > poor countries of the world.
 
 So basically, if [colonialism](https://en.wikipedia.org/wiki/Colonialism) is Europeans bringing genocide, war,
-and religion to the Americas, neo-colonialism is the Americans (note
-the "n") bringing capitalism to the world.
+and its religion to the Africa, Asia, and the Americas,
+neo-colonialism is the Americans (note the "n") bringing capitalism to
+the world.
 
 Before we see how this applies to the Internet, we must therefore make
 a detour into US history. This matters, because anyone would be

publish
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index 879c70fa..5468b5c0 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -442,4 +442,5 @@ And now it feels like the west coast has won over the east coast, or
 maybe it recolonized it. In any case, Internet now [christens
 emperors](https://en.wikipedia.org/wiki/2016_United_States_presidential_election).
 
-[[!tag draft]]
+[[!tag debian-planet reflexion politics tech diversity ethics internet history colonialism]]
+

creating tag page tag/colonialism
diff --git a/tag/colonialism.mdwn b/tag/colonialism.mdwn
new file mode 100644
index 00000000..820b3a89
--- /dev/null
+++ b/tag/colonialism.mdwn
@@ -0,0 +1,4 @@
+[[!meta title="pages tagged colonialism"]]
+
+[[!inline pages="tagged(colonialism)" actions="no" archive="yes"
+feedshow=10]]

try to make a better link
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index 225b2b76..879c70fa 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -290,8 +290,9 @@ which creates a "lack of agency and individual freedom":
 > therefore use this to create their own space with their own norms,
 > shaping their online world according to their own outlook.
 
-{Interestingly, the spread of the aforementioned "social contract" was
-prophesized by Barlow in the Declaration:} {link with before?}
+But the digital divide is certainly not the worst problem we have to
+deal with on the Internet today. Going back to the Declaration, we
+originally believed we were creating an entirely new world:
 
 > This governance will arise according to the conditions of our
 > world, not yours. Our world is different.
@@ -322,7 +323,7 @@ pandemic, workers were being [dangerously exposed to the virus](https://www.poli
 warehouses. All this while Amazon is basically taking over [the entire
 economy](https://www.vice.com/en/article/7xpgvx/amazons-is-trying-to-control-the-underlying-infrastructure-of-our-economy).
 
-The Declaration culminates with this other prophecy:
+The Declaration culminates with this prophecy:
 
 > We will spread ourselves across the Planet so that no one can arrest
 > our thoughts.

more edits, one todo
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index 23a80101..225b2b76 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -2,13 +2,11 @@
 
 [[!toc]]
 
-Born in the previous millennia, I grew up with the Internet and the
-[declaration of independence of cyberspace][]. The ethics and politics
-of the Internet have always been important in my life, but I have also
-been involved at other political levels, [against police
-brutality](https://cobp.resist.ca/), for [Food, Not Bombs](https://foodnotbombs.net/), [worker autonomy][koumbit],
-[software freedom](https://www.debian.org/), etc. For a long time, those things seem to be
-coherent and cohesive: it all made sense.
+I grew up with the Internet and its ethics and politics have always
+been important in my life. But I have also been involved at other
+levels, [against police brutality](https://cobp.resist.ca/), for [Food, Not Bombs](https://foodnotbombs.net/),
+[worker autonomy][koumbit], [software freedom](https://www.debian.org/), etc. For a long time,
+that all seemed coherent.
 
 [koumbit]: https://www.koumbit.org/
 [declaration of independence of cyberspace]: https://www.eff.org/cyberspace-independence
@@ -39,18 +37,16 @@ Imperialism* (1965), he wrote:
 > the exploitation rather than for the development of the less
 > developed parts of the world. Investment, under neo-colonialism,
 > increases, rather than decreases, the gap between the rich and the
-> poor countries of the world. The struggle against neo-colonialism is
-> not aimed at excluding the capital of the developed world from
-> operating in less developed countries.
+> poor countries of the world.
 
 So basically, if [colonialism](https://en.wikipedia.org/wiki/Colonialism) is Europeans bringing genocide, war,
 and religion to the Americas, neo-colonialism is the Americans (note
 the "n") bringing capitalism to the world.
 
-Before we see how this applies to the Internet, we must make a detour
-into US history. This matters, because anyone would be hard-pressed to
-decouple neo-colonialism from the empire under which it evolves, and
-here we can only name the United States of America.
+Before we see how this applies to the Internet, we must therefore make
+a detour into US history. This matters, because anyone would be
+hard-pressed to decouple neo-colonialism from the empire under which
+it evolves, and here we can only name the United States of America.
 
 # US Declaration of Independence
 
@@ -72,8 +68,8 @@ In that aging document, we find the following pearl:
 > unalienable Rights, that among these are Life, Liberty and the
 > pursuit of Happiness.
 
-I would therefore also argue that, as a founding document, it still
-has an impact in the sense that the above quote has been called an:
+As a founding document, the Declaration still has an impact in the
+sense that the above quote has been called an:
 
 > "immortal declaration", and "perhaps [the] single phrase" of the
 > American Revolutionary period with the greatest "continuing
@@ -95,13 +91,13 @@ grievances](https://en.wikipedia.org/wiki/Grievances_of_the_United_States_Declar
 > destruction of all ages, sexes and conditions.
 
 This is a clear mark of the [frontier myth](https://en.wikipedia.org/wiki/Frontier_myth) which paved the way for
-the US to exterminate and colonize the territory we now call the
+the US to exterminate and colonize the territory some now call the
 United States of America.
 
-As such, the declaration of independence is a colonial document,
+The declaration of independence is obviously a colonial document,
 having being written by colonists. None of this is particularly
 surprising, historically, but I figured it serves as a good reminder
-of where we're coming from, since the Internet was born in the US.
+of where the Internet is coming from, since it was born in the US.
 
 # A Declaration of the Independence of Cyberspace
 
@@ -121,7 +117,8 @@ not lie within your borders*". In that sense, cyberspace is the [final
 frontier](https://en.wikipedia.org/wiki/Final_Frontier): having failed to colonize the moon, Americans turn
 inwards, deeper into technology, but still in the frontier
 ideology. And indeed, Barlow is one of the co-founder of the
-[Electronic Frontier Foundation](https://en.wikipedia.org/wiki/Electronic_Frontier_Foundation), which was founded six years prior.
+Electronic *Frontier* Foundation (the beloved [EFF](https://en.wikipedia.org/wiki/Electronic_Frontier_Foundation)), founded six
+years prior.
 
 But there are other problems with this idea. As [Wikipedia quotes](https://en.wikipedia.org/wiki/A_Declaration_of_the_Independence_of_Cyberspace#Critical_response):
 
@@ -140,7 +137,7 @@ one could argue, made the Internet possible.
 (From there on, "backbone" providers could start competing and emerge,
 and eventually coalesce into new monopolies: Google has a monopoly on
 search and advertistement, Facebook on communications for a few
-generations, Amazon on storage and compute, Microsoft on hardware,
+generations, Amazon on storage and computing, Microsoft on hardware,
 etc. Even AT&T is now pretty much as consolidated as it was
 before.)
 
@@ -159,10 +156,10 @@ But back to the Declaration:
 > construction project. You cannot. It is an act of nature and it
 > grows itself through our collective actions.
 
-In other words, a "public construction project" is unnatural. And
-indeed, the modern "nature" of development is private: most of the
-Internet is now privately owned and operated. In Barlow's mind, the
-"public" is bad, and private is good, natural.
+In Barlow's mind, the "public" is bad, and private is good,
+natural. Or, in other words, a "public construction project" is
+unnatural. And indeed, the modern "nature" of development is private:
+most of the Internet is now privately owned and operated.
 
 I must admit that, as an anarchist, I loved that sentence when I read
 it. I was rooting for "us", the underdogs, the revolutionaries. And,
@@ -176,9 +173,9 @@ ago.
 Now, the infrastructure of the Internet has zero accountability to
 traditional political entities supposedly representing the people, or
 even its users. The situation is actually *worse* than when the US was
-founded (6% of the population can vote), because the owners of the
+founded (e.g. "6% of the population can vote"), because the owners of the
 tech giants are only a handful of people who can override any
-decision. There's only one Amazon CEO, he's called Jeff Besos, and he
+decision. There's only one Amazon CEO, he's called Jeff Bezos, and he
 has total control.
 
 # Social Contract
@@ -188,7 +185,7 @@ Here's another claim of the Declaration:
 > We are forming our own Social Contract.
 
 I remember the early days, back when "[netiquette](https://en.wikipedia.org/wiki/Etiquette_in_technology#Netiquette)" was a word, it
-felt that we had some sort of a contract. Not written in standards of
+did feel we had some sort of a contract. Not written in standards of
 course -- or barely (see [RFC1855](https://datatracker.ietf.org/doc/html/rfc1855)) -- but as a tacit
 agreement. How wrong we were. One just needs to look at Facebook to
 see how problematic that idea is on a global network.
@@ -198,14 +195,14 @@ Zuckerberg [explicitly refused](https://www.theguardian.com/technology/2020/may/
 implicitly means he will let lies take over its platforms. 
 
 He also sees Facebook as place where everyone is equal, something
-that's also echoed in the Declaration:
+that echoes the Declaration:
 
 > We are creating a world that all may enter without privilege or
 > prejudice accorded by race, economic power, military force, or
 > station of birth.
 
-(We note, in passing, the omission of gender in that list, going back
-to the infamous "All men are created equal" claim of the US
+(We note, in passing, the omission of gender in that list, also
+mirroring the infamous "All men are created equal" claim of the US
 declaration.)
 
 As the Wall Street Journal's (WSJ) [Facebook files](https://www.wsj.com/articles/the-facebook-files-11631713039) later shown,
@@ -214,31 +211,31 @@ both of those have serious limitations inside Facebook. There are
 [fascists](https://en.wikipedia.org/wiki/Trumpism) and [rapists](https://en.wikipedia.org/wiki/Neymar). Drug cartels and human traffickers
 [thrive on the platform](https://www.wsj.com/articles/facebook-drug-cartels-human-traffickers-response-is-weak-documents-11631812953?mod=article_inline). Even when Zuckerberg himself tried to
 tame the platform -- to get people [vaccinated](https://www.wsj.com/articles/facebook-mark-zuckerberg-vaccinated-11631880296?mod=article_inline) or to make it
-[healthier](https://www.wsj.com/articles/facebook-algorithm-change-zuckerberg-11631654215?mod=article_inline) -- he failed: "vaxxer" conspiracies thrived and
+[healthier](https://www.wsj.com/articles/facebook-algorithm-change-zuckerberg-11631654215?mod=article_inline) -- he failed: "vaxxer" conspiracies multiplied and
 Facebook got *angrier*.
 
 This is because the "social contract" behind Facebook and those large
-companies is a lie: their concern is profit and that means with
+companies is a lie: their concern is profit and that means
 advertising, "engagement" with the platform, which [causes increased
 anxiety and depression in teens](https://www.bbc.com/news/technology-58570353), for example.
 
 Facebook's response to this is that they are working really hard on
 moderation. But the truth is that even that system is severely
 skewed. The WSJ showed that Facebook has translators for only 50
-languages. It's a [surprisingly hard thing to count](https://www.linguisticsociety.org/content/how-many-languages-are-there-world) but estimates
-range the number of distinct human languages between 2500 and 7000. So
-while 50 languages seems big at first, it's actually a tiny fraction
-of the human population using Facebook. Taking the first 50 of the
-[Wikipedia list of languages by native speakers](https://en.wikipedia.org/wiki/List_of_languages_by_number_of_native_speakers) we miss languages
-like Dutch (52), Greek (74), and Hungarian (78), and that's just a few
-random nations picks from Europe.
-
-As an example of this, Facebook has trouble moderating even a major
-language like Arabic. It censored content from legitimate Arab news
-sources because they mentioned the word [al-Aqsa](https://en.wikipedia.org/wiki/Al-Aqsa) because they
-associate it with the [al-Aqsa Martyrs' Brigades](https://en.wikipedia.org/wiki/Al-Aqsa_Martyrs%27_Brigades) when they were
-talking about the [Al-Aqsa Mosque](https://en.wikipedia.org/wiki/Al-Aqsa_Mosque)... This bias against Arabs also
-shows how Facebook reproduces the US state colonizer politics.
+languages. It's a [surprisingly hard to count human languages](https://www.linguisticsociety.org/content/how-many-languages-are-there-world) but
+estimates range the number of distinct languages between 2500
+and 7000. So while 50 languages seems big at first, it's actually a
+tiny fraction of the human population using Facebook. Taking the first
+50 of the [Wikipedia list of languages by native speakers](https://en.wikipedia.org/wiki/List_of_languages_by_number_of_native_speakers) we omit
+languages like Dutch (52), Greek (74), and Hungarian (78), and that's
+just a few random nations picks from Europe.
+
+As an example, Facebook has trouble moderating even a major language
+like Arabic. It censored content from legitimate Arab news sources
+when they mentioned the word [al-Aqsa](https://en.wikipedia.org/wiki/Al-Aqsa) because Facebook associates
+it with the [al-Aqsa Martyrs' Brigades](https://en.wikipedia.org/wiki/Al-Aqsa_Martyrs%27_Brigades) when they were talking
+about the [Al-Aqsa Mosque](https://en.wikipedia.org/wiki/Al-Aqsa_Mosque)... This bias against Arabs also shows
+how Facebook reproduces the American colonizer politics.
 
 The WSJ also pointed out that Facebook spends only 13% of its
 moderation efforts outside of the US, even if that represents 90% of
@@ -269,12 +266,12 @@ And just like Lewis and Clark, Google has a strong military
 component. For example, Google Earth was not originally built at
 Google but is the acquisition of a company called Keyhole which had
 [ties with the CIA](https://en.wikipedia.org/wiki/Google_Earth#History). Those ties were [brought inside Google during

(Diff truncated)
nitpick
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index 4d0ad24a..23a80101 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -434,7 +434,7 @@ warning about abusing the word like I am sort of doing here:
 
 Another good read is the classic [Code and other laws of
 cyberspace](https://lessig.org/product/code) (1999, [free PDF](https://lessig.org/images/resources/1999-Code.pdf)) which is also critical of
-Barlow's Declaration. In "Code is law", Lawrence Lessig argues that
+Barlow's Declaration. In "Code is law", Lawrence Lessig argues that:
 
 > computer code (or "West Coast Code", referring to Silicon Valley)
 > regulates conduct in much the same way that legal code (or "East

final review
this is now my third longest article ever, after ignoring two email
articles that have a lot of copy-paste (2016-05-12-email-setup.mdwn
and 2021-03-22-email-crash.md).
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index 27b1aaa8..4d0ad24a 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -57,9 +57,9 @@ here we can only name the United States of America.
 Let's start with the [United States declaration of independence](https://en.wikipedia.org/wiki/United_States_Declaration_of_Independence)
 (1776). Many Americans may roll their eyes at this, possibly because
 that declaration is not actually part of the [US constitution](https://en.wikipedia.org/wiki/Constitution_of_the_United_States) and
-therefore may have questionable legal standing. It was obviously a
-driving philosophical force in the founding of the nation. As its
-author, Thomas Jefferson, stated:
+therefore may have questionable legal standing. Still, it was
+obviously a driving philosophical force in the founding of the
+nation. As its author, Thomas Jefferson, stated:
 
 > it was intended to be an expression of the American mind, and to
 > give to that expression the proper tone and spirit called for by the
@@ -110,8 +110,9 @@ wrote a [declaration of independence of cyberspace][declaration of independence
 point, ([almost](https://en.wikipedia.org/wiki/Voting_rights_in_the_United_States)) everyone has a right to vote (including women),
 slavery was abolished (although [some argue it still exists in the
 form of the prison system](https://en.wikipedia.org/wiki/Angela_Davis#Political_activism_and_speeches)); the US has made tremendous
-progress. So this text will have aged better than the previous
-declaration it is obviously derived from? Let's see.
+progress. Surely this text will have aged better than the previous
+declaration it is obviously derived from. Let's see how it reads today
+and how it maps to how the Internet is actually built now.
 
 # Borders of Independence
 
@@ -120,7 +121,7 @@ not lie within your borders*". In that sense, cyberspace is the [final
 frontier](https://en.wikipedia.org/wiki/Final_Frontier): having failed to colonize the moon, Americans turn
 inwards, deeper into technology, but still in the frontier
 ideology. And indeed, Barlow is one of the co-founder of the
-[Electronic Frontier Foundation](https://en.wikipedia.org/wiki/Electronic_Frontier_Foundation), which was founded 6 years prior.
+[Electronic Frontier Foundation](https://en.wikipedia.org/wiki/Electronic_Frontier_Foundation), which was founded six years prior.
 
 But there are other problems with this idea. As [Wikipedia quotes](https://en.wikipedia.org/wiki/A_Declaration_of_the_Independence_of_Cyberspace#Critical_response):
 
@@ -146,7 +147,7 @@ before.)
 The point is: all those companies have gigantic data centers and
 intercontinental cables. And those are definitely prioritizing the
 western world, the heart of the empire. To take an example, [Google's
-latest 3900 mile undersea cable](https://www.cnet.com/tech/google-finishes-3900-mile-subsea-cable-connecting-us-to-uk-and-spain/) does not connect Argentina to
+latest 3,900 mile undersea cable](https://www.cnet.com/tech/google-finishes-3900-mile-subsea-cable-connecting-us-to-uk-and-spain/) does not connect Argentina to
 South Africa or New Zealand, it connects the US to UK and
 Spain. Hardly a revolutionary prospect.
 
@@ -158,14 +159,10 @@ But back to the Declaration:
 > construction project. You cannot. It is an act of nature and it
 > grows itself through our collective actions.
 
-Here, we imply that "nature" is not a "public construction
-project". And indeed, the modern "nature" of development is private:
-most of the Internet is now privately owned and operated. Amazon hosts
-a majority of cloud content, and the rest is hosted by other large
-corporations. In Barlow's mind, the "public" is bad, and private is
-good, natural. This fails to consider basic accountability principles
-that things like governments have been designed to address, warts and
-all.
+In other words, a "public construction project" is unnatural. And
+indeed, the modern "nature" of development is private: most of the
+Internet is now privately owned and operated. In Barlow's mind, the
+"public" is bad, and private is good, natural.
 
 I must admit that, as an anarchist, I loved that sentence when I read
 it. I was rooting for "us", the underdogs, the revolutionaries. And,
@@ -173,7 +170,16 @@ in a way, I still do: I am on the board of [Koumbit][] and work for a
 [non-profit](https://www.torproject.org/) that has pivoted towards censorship and surveillance
 evasion. Yet I cannot help but think that, as a whole, we have failed
 to establish that independence and put too much trust in private
-companies. It is obvious in retrospect, but it was not, 30 years ago.
+companies. It is obvious in retrospect, but it was not, 30 years
+ago.
+
+Now, the infrastructure of the Internet has zero accountability to
+traditional political entities supposedly representing the people, or
+even its users. The situation is actually *worse* than when the US was
+founded (6% of the population can vote), because the owners of the
+tech giants are only a handful of people who can override any
+decision. There's only one Amazon CEO, he's called Jeff Besos, and he
+has total control.
 
 # Social Contract
 
@@ -189,7 +195,7 @@ see how problematic that idea is on a global network.
 
 Facebook is the quintessential "hacker" ideology put in practice. Mark
 Zuckerberg [explicitly refused](https://www.theguardian.com/technology/2020/may/28/zuckerberg-facebook-police-online-speech-trump) to be "arbiter of truth" which
-implicitly means it will let lies take over its platforms. 
+implicitly means he will let lies take over its platforms. 
 
 He also sees Facebook as place where everyone is equal, something
 that's also echoed in the Declaration:
@@ -205,63 +211,64 @@ declaration.)
 As the Wall Street Journal's (WSJ) [Facebook files](https://www.wsj.com/articles/the-facebook-files-11631713039) later shown,
 both of those have serious limitations inside Facebook. There are
 [VIPs who systematically bypass moderation systems](https://www.wsj.com/articles/facebook-files-xcheck-zuckerberg-elite-rules-11631541353) including
-Trumpists and rapists. Drug cartels and human traffickers [thrive on
-the platform](https://www.wsj.com/articles/facebook-drug-cartels-human-traffickers-response-is-weak-documents-11631812953?mod=article_inline). Even when Zuckerberg himself tried to tame the
-platform -- to get people [vaccinated](https://www.wsj.com/articles/facebook-mark-zuckerberg-vaccinated-11631880296?mod=article_inline) or to make it [healthier](https://www.wsj.com/articles/facebook-algorithm-change-zuckerberg-11631654215?mod=article_inline)
--- he failed: "vaxxer" conspiracies thrived and Facebook got
-*angrier*.
+[fascists](https://en.wikipedia.org/wiki/Trumpism) and [rapists](https://en.wikipedia.org/wiki/Neymar). Drug cartels and human traffickers
+[thrive on the platform](https://www.wsj.com/articles/facebook-drug-cartels-human-traffickers-response-is-weak-documents-11631812953?mod=article_inline). Even when Zuckerberg himself tried to
+tame the platform -- to get people [vaccinated](https://www.wsj.com/articles/facebook-mark-zuckerberg-vaccinated-11631880296?mod=article_inline) or to make it
+[healthier](https://www.wsj.com/articles/facebook-algorithm-change-zuckerberg-11631654215?mod=article_inline) -- he failed: "vaxxer" conspiracies thrived and
+Facebook got *angrier*.
 
 This is because the "social contract" behind Facebook and those large
-companies is a lie: their concern is profits and that goes with
-advertising, "engagement" with the platform, which creates [causes
-increased anxiety and depression in teens](https://www.bbc.com/news/technology-58570353), for example.
+companies is a lie: their concern is profit and that means with
+advertising, "engagement" with the platform, which [causes increased
+anxiety and depression in teens](https://www.bbc.com/news/technology-58570353), for example.
 
 Facebook's response to this is that they are working really hard on
 moderation. But the truth is that even that system is severely
 skewed. The WSJ showed that Facebook has translators for only 50
 languages. It's a [surprisingly hard thing to count](https://www.linguisticsociety.org/content/how-many-languages-are-there-world) but estimates
-of distinct human languages range between 2500 and 7000. So while 50
-languages seems big at first, it's actually a tiny fraction of the
-human population using Facebook. Taking the first 50 of the [Wikipedia
-list of languages by native speakers](https://en.wikipedia.org/wiki/List_of_languages_by_number_of_native_speakers) we miss languages like Dutch
-(52), Greek (74), and Hungarian (78), and that's just a few random
-nations picks from Europe.
-
-As an example, Facebook has trouble moderating even a major language
-like Arabic. It censored content from legitimate Arab news sources
-because they mentioned the word [al-Aqsa](https://en.wikipedia.org/wiki/Al-Aqsa) because they associate it
-with the [al-Aqsa Martyrs' Brigades](https://en.wikipedia.org/wiki/Al-Aqsa_Martyrs%27_Brigades) when they were talking about
-the [Al-Aqsa Mosque](https://en.wikipedia.org/wiki/Al-Aqsa_Mosque)...
+range the number of distinct human languages between 2500 and 7000. So
+while 50 languages seems big at first, it's actually a tiny fraction
+of the human population using Facebook. Taking the first 50 of the
+[Wikipedia list of languages by native speakers](https://en.wikipedia.org/wiki/List_of_languages_by_number_of_native_speakers) we miss languages
+like Dutch (52), Greek (74), and Hungarian (78), and that's just a few
+random nations picks from Europe.
+
+As an example of this, Facebook has trouble moderating even a major
+language like Arabic. It censored content from legitimate Arab news
+sources because they mentioned the word [al-Aqsa](https://en.wikipedia.org/wiki/Al-Aqsa) because they
+associate it with the [al-Aqsa Martyrs' Brigades](https://en.wikipedia.org/wiki/Al-Aqsa_Martyrs%27_Brigades) when they were
+talking about the [Al-Aqsa Mosque](https://en.wikipedia.org/wiki/Al-Aqsa_Mosque)... This bias against Arabs also
+shows how Facebook reproduces the US state colonizer politics.
 
 The WSJ also pointed out that Facebook spends only 13% of its
 moderation efforts outside of the US, even if that represents 90% of
-its users. Facebook also spends three more times moderating on "brand
-safety", which again shows its priority is not the safety of its
-users, but of the advertisers. Its bias against Arabs also shows how
-Facebook reproduces the US state colonizer politics.
+its users. Facebook spends three more times moderating on "brand
+safety", which shows its priority is not the safety of its users, but
+of the advertisers.
 
 # Military Internet
 
 [Sergey Brin](https://en.wikipedia.org/wiki/Sergey_Brin) and [Larry Page](https://en.wikipedia.org/wiki/Larry_Page) are the [Lewis and Clark](https://en.wikipedia.org/wiki/Lewis_and_Clark_Expedition) of
-our generation. Just like the latter were sent by Jefferson to declare
-sovereignty over the entire US west coast, Google declared sovereignty
-over all human knowledge, with its mission statement "to organize the
-world's information and make it universally accessible and
-useful". (It should be noted that Page somewhat [questioned that
+our generation. Just like the latter were sent by Jefferson (the same)
+to declare sovereignty over the entire US west coast, Google declared
+sovereignty over all human knowledge, with its mission statement "to
+organize the world's information and make it universally accessible
+and useful". (It should be noted that Page somewhat [questioned that
 mission](https://www.theguardian.com/technology/2014/nov/03/larry-page-google-dont-be-evil-sergey-brin) but only because it was not ambitious enough, Google
 having "outgrown" it.)
 
 The Lewis and Clark expedition, just like Google, had a scientific
 pretext, because that is what you do to colonize a world,
-presumably. Yet both men were military: the [Corps of Discovery](https://en.wikipedia.org/wiki/Corps_of_Discovery)
-was made up of a few dozen enlisted men and a dozen civilians,
-including [York][] an African American slave *owned* by Clark and
-*sold* after the expedition, with its final fate lost in history.
-
-And just like Lewis and Clark, Google has a strong military component
-to it. For example, Google Earth was not originally built at Google
-but is based on the acquisition of a company called Keyhole which had
-[ties with the CIA](https://en.wikipedia.org/wiki/Google_Earth#History) and those ties were [brought in Google during
+presumably. Yet both men were military and had to receive scientific
+training before they left. The [Corps of Discovery](https://en.wikipedia.org/wiki/Corps_of_Discovery) was made up of
+a few dozen enlisted men and a dozen civilians, including [York][] an
+African American slave *owned* by Clark and *sold* after the
+expedition, with his final fate lost in history.
+
+And just like Lewis and Clark, Google has a strong military
+component. For example, Google Earth was not originally built at
+Google but is the acquisition of a company called Keyhole which had
+[ties with the CIA](https://en.wikipedia.org/wiki/Google_Earth#History). Those ties were [brought inside Google during
 the acquisition](https://pando.com/2014/03/07/the-google-military-surveillance-complex/). The increasing investment of Google inside the
 military-industrial complex eventually led to Google workers
 [organizing a revolt](https://en.wikipedia.org/wiki/Google_worker_organization) although it is currently unclear how involved
@@ -295,28 +302,25 @@ prophesized by Barlow in the Declaration:
 How I [dearly wished that was true](https://en.wikipedia.org/wiki/Eternal_September). Unfortunately, the Internet is
 not that different from the offline world. Or, to be more accurate,
 the values we have embedded in the Internet, particularly of free

(Diff truncated)
capital I internet
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index 4e40d8c5..27b1aaa8 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -13,7 +13,7 @@ coherent and cohesive: it all made sense.
 [koumbit]: https://www.koumbit.org/
 [declaration of independence of cyberspace]: https://www.eff.org/cyberspace-independence
 
-But the more I look at the modern internet -- and the
+But the more I look at the modern Internet -- and the
 mega-corporations that control it -- and the less confidence I have in
 my original political analysis of the liberating potential of
 technology. I have come to believe that most of our technological
@@ -47,7 +47,7 @@ So basically, if [colonialism](https://en.wikipedia.org/wiki/Colonialism) is Eur
 and religion to the Americas, neo-colonialism is the Americans (note
 the "n") bringing capitalism to the world.
 
-Before we see how this applies to the internet, we must make a detour
+Before we see how this applies to the Internet, we must make a detour
 into US history. This matters, because anyone would be hard-pressed to
 decouple neo-colonialism from the empire under which it evolves, and
 here we can only name the United States of America.
@@ -127,14 +127,14 @@ But there are other problems with this idea. As [Wikipedia quotes](https://en.wi
 > The declaration has been criticized for internal
 > inconsistencies.[[9](https://web.archive.org/web/20161105174638/http://ieet.org/index.php/IEET/more/evans0220)] The declaration's assertion that
 > 'cyberspace' is a place removed from the physical world has also
-> been challenged by people who point to the fact that the internet is
+> been challenged by people who point to the fact that the Internet is
 > always linked to its underlying geography.[[10](https://doi.org/10.1111%2Fgeoj.12009<)]
 
-And indeed, the internet is definitely a physical object. First
+And indeed, the Internet is definitely a physical object. First
 controlled and severely restricted by "telcos" like AT&T, it was
 somewhat "liberated" from that monopoly in 1982 when an [anti-trust
 lawsuit](https://en.wikipedia.org/wiki/United_States_v._AT%26T) [broke up the monopoly](https://en.wikipedia.org/wiki/Breakup_of_the_Bell_System), a key historical event that,
-one could argue, made the internet possible.
+one could argue, made the Internet possible.
 
 (From there on, "backbone" providers could start competing and emerge,
 and eventually coalesce into new monopolies: Google has a monopoly on
@@ -160,7 +160,7 @@ But back to the Declaration:
 
 Here, we imply that "nature" is not a "public construction
 project". And indeed, the modern "nature" of development is private:
-most of the internet is now privately owned and operated. Amazon hosts
+most of the Internet is now privately owned and operated. Amazon hosts
 a majority of cloud content, and the rest is hosted by other large
 corporations. In Barlow's mind, the "public" is bad, and private is
 good, natural. This fails to consider basic accountability principles
@@ -276,7 +276,7 @@ happily bidding on military contracts all the time.
 I am obviously not the first to identify colonial structures in the
 Internet. In an article titled [The Internet as an Extension of
 Colonialism](https://thesecuritydistillery.org/all-articles/the-internet-as-an-extension-of-colonialism), Heather McDonald correctly identifies fundamental
-problems with the "development" of new "markets" of internet
+problems with the "development" of new "markets" of Internet
 "consumers", primarily arguing that it creates a [digital divide](https://en.wikipedia.org/wiki/Digital_divide)
 which creates a "lack of agency and individual freedom":
 
@@ -292,7 +292,7 @@ prophesized by Barlow in the Declaration:
 > This governance will arise according to the conditions of our
 > world, not yours. Our world is different.
 
-How I [dearly wished that was true](https://en.wikipedia.org/wiki/Eternal_September). Unfortunately, the internet is
+How I [dearly wished that was true](https://en.wikipedia.org/wiki/Eternal_September). Unfortunately, the Internet is
 not that different from the offline world. Or, to be more accurate,
 the values we have embedded in the Internet, particularly of free
 speech absolutism, sexism, corporatism, and exploitation ethics, are
@@ -301,18 +301,18 @@ now exploding outside of the Internet and into the real world.
 That's because the Internet is part of the world, it is both being
 changed by it and changing it.
 
-The internet was built with free software which, fundamentally, was
+The Internet was built with free software which, fundamentally, was
 based on quasi-volunteer labour of an elite force of white men with
 obviously too much time on their hands (and also: no children). The
 mythical writing of GCC and Emacs by Richard Stallman is a good
-example of this, but the entirety of the internet now seems to be
+example of this, but the entirety of the Internet now seems to be
 running on random bits and pieces running by hit-and-run programmers
 working on their copious free time. Whenever any of those [fails](https://www.davidhaney.io/npm-left-pad-have-we-forgotten-how-to-program/),
 it can [compromise](https://lwn.net/Articles/773121/) or bring down entire systems. (Heck, I wrote
 *this article* on my day off...)
 
 This model of what is fundamentally "cheap labour" is spreading
-outwards from the internet. Delivery workers are being exploited to
+outwards from the Internet. Delivery workers are being exploited to
 the bone by apps like Uber -- although it should be noted that workers
 still [organise and fight back](https://www.curbed.com/article/nyc-delivery-workers.html). Amazon workers are similarly
 exploited beyond belief, being forbidden to take breaks so much that
@@ -330,7 +330,7 @@ This prediction, which first felt revolutionary, is now chilling.
 
 # Colonial Internet
 
-The internet is, if not neo-colonial, plain colonial. The US colonies
+The Internet is, if not neo-colonial, plain colonial. The US colonies
 had cotton fields and slaves, we have [disposable cell phones](https://www.jacobinmag.com/2015/03/smartphone-usage-technology-aschoff/) and
 [Foxconn workers](https://www.theguardian.com/technology/2017/jun/18/foxconn-life-death-forbidden-city-longhua-suicide-apple-iphone-brian-merchant-one-device-extract). Canada has its [cultural genocide](https://www.thecanadianencyclopedia.ca/en/article/genocide-and-indigenous-peoples-in-canada), Facebook
 has his own genocides in [Ethiopia](https://www.vice.com/en_us/article/xg897a/hate-speech-on-facebook-is-pushing-ethiopia-dangerously-close-to-a-genocide), [Myanmar](https://www.salon.com/2020/08/20/facebook-is-a-global-threat-to-public-health-avaaz-report-says/), and mob violence

uniform headings
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index 222d0759..4e40d8c5 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -52,7 +52,7 @@ into US history. This matters, because anyone would be hard-pressed to
 decouple neo-colonialism from the empire under which it evolves, and
 here we can only name the United States of America.
 
-# US Declaration of independence
+# US Declaration of Independence
 
 Let's start with the [United States declaration of independence](https://en.wikipedia.org/wiki/United_States_Declaration_of_Independence)
 (1776). Many Americans may roll their eyes at this, possibly because
@@ -113,7 +113,7 @@ form of the prison system](https://en.wikipedia.org/wiki/Angela_Davis#Political_
 progress. So this text will have aged better than the previous
 declaration it is obviously derived from? Let's see.
 
-# The borders of independence
+# Borders of Independence
 
 One of the key ideas that Barlow brings up is that "*cyberspace does
 not lie within your borders*". In that sense, cyberspace is the [final
@@ -150,7 +150,7 @@ latest 3900 mile undersea cable](https://www.cnet.com/tech/google-finishes-3900-
 South Africa or New Zealand, it connects the US to UK and
 Spain. Hardly a revolutionary prospect.
 
-# The Private Internet
+# Private Internet
 
 But back to the Declaration:
 
@@ -175,7 +175,7 @@ evasion. Yet I cannot help but think that, as a whole, we have failed
 to establish that independence and put too much trust in private
 companies. It is obvious in retrospect, but it was not, 30 years ago.
 
-# The Social Contract
+# Social Contract
 
 Here's another claim of the Declaration:
 
@@ -240,7 +240,7 @@ safety", which again shows its priority is not the safety of its
 users, but of the advertisers. Its bias against Arabs also shows how
 Facebook reproduces the US state colonizer politics.
 
-# The military internet
+# Military Internet
 
 [Sergey Brin](https://en.wikipedia.org/wiki/Sergey_Brin) and [Larry Page](https://en.wikipedia.org/wiki/Larry_Page) are the [Lewis and Clark](https://en.wikipedia.org/wiki/Lewis_and_Clark_Expedition) of
 our generation. Just like the latter were sent by Jefferson to declare
@@ -271,7 +271,7 @@ happily bidding on military contracts all the time.
 
 [York]: https://en.wikipedia.org/wiki/York_(explorer)
 
-# The "spreading" of the Internet
+# Spreading the Internet
 
 I am obviously not the first to identify colonial structures in the
 Internet. In an article titled [The Internet as an Extension of
@@ -328,7 +328,7 @@ The Declaration culminates with this other prophecy:
 
 This prediction, which first felt revolutionary, is now chilling.
 
-# The colonial internet
+# Colonial Internet
 
 The internet is, if not neo-colonial, plain colonial. The US colonies
 had cotton fields and slaves, we have [disposable cell phones](https://www.jacobinmag.com/2015/03/smartphone-usage-technology-aschoff/) and

formatting
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index f3d84179..222d0759 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -418,17 +418,12 @@ And they introduce another definition of Neo-colonialism:
 > on postcolonial studies. In an email, Bahri summed up those
 > similarities in list form:
 > 
->     1. ride in like the savior
-> 
->     2. bandy about words like equality, democracy, basic rights
-> 
->     3. mask the long-term profit motive (see 2 above)
-> 
->     4. justify the logic of partial dissemination as better than nothing
-> 
->     5. partner with local elites and vested interests
-> 
->     6. accuse the critics of ingratitude 
+> 1. ride in like the savior
+> 2. bandy about words like equality, democracy, basic rights
+> 3. mask the long-term profit motive (see 2 above)
+> 4. justify the logic of partial dissemination as better than nothing
+> 5. partner with local elites and vested interests
+> 6. accuse the critics of ingratitude 
 > 
 > “In the end,” she told me, “if it isn’t a duck, it shouldn’t quack
 > like a duck.”

one more edit, this is almost not a draft...
but i'll wait for my precious reviewers' feedback before going on
feed.
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index 4170bf0a..f3d84179 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -1,27 +1,25 @@
 [[!meta title="The Neo-Colonial Internet"]]
 
-> This article is a draft and still needs to be completed.
-
 [[!toc]]
 
-Having been born in the previous millennia, I grew up with the
-Internet and the [declaration of independence of cyberspace][]. The
-ethics and politics of the Internet have always been important in my
-life, but I have also been involved at other political levels,
-[against police brutality](https://cobp.resist.ca/), for [Food, Not Bombs](https://foodnotbombs.net/), [worker
-autonomy][koumbit], [software freedom](https://www.debian.org/), etc. For a long time, those
-things seem to be coherent and cohesive: it made sense.
+Born in the previous millennia, I grew up with the Internet and the
+[declaration of independence of cyberspace][]. The ethics and politics
+of the Internet have always been important in my life, but I have also
+been involved at other political levels, [against police
+brutality](https://cobp.resist.ca/), for [Food, Not Bombs](https://foodnotbombs.net/), [worker autonomy][koumbit],
+[software freedom](https://www.debian.org/), etc. For a long time, those things seem to be
+coherent and cohesive: it all made sense.
 
 [koumbit]: https://www.koumbit.org/
 [declaration of independence of cyberspace]: https://www.eff.org/cyberspace-independence
 
-But the more I look at the modern internet -- and the large
-corporations that control it -- and the less confidence I have in my
-original political analysis of the liberating potential of
+But the more I look at the modern internet -- and the
+mega-corporations that control it -- and the less confidence I have in
+my original political analysis of the liberating potential of
 technology. I have come to believe that most of our technological
 development is harmful to the large majority of the population of the
-planet, and of course the rest of the biosphere. And not only this, I
-have the feeling this has been a problem all along.
+planet, and of course the rest of the biosphere. And now I feel this
+is not a new problem.
 
 This is because the Internet is a neo-colonial device, and has been
 from the start. Let me explain.
@@ -29,8 +27,8 @@ from the start. Let me explain.
 # What is Neo-Colonialism?
 
 The term "[neo-colonialism](https://en.wikipedia.org/wiki/Neocolonialism)" was coined by [Kwame Nkrumah](https://en.wikipedia.org/wiki/Kwame_Nkrumah),
-first president of [Ghana](https://en.wikipedia.org/wiki/Ghana) (1960–66). In *Neo-Colonialism, the Last
-Stage of Imperialism* (1965), Kwame Nkrumah wrote:
+first president of [Ghana](https://en.wikipedia.org/wiki/Ghana). In *Neo-Colonialism, the Last Stage of
+Imperialism* (1965), he wrote:
 
 > In place of colonialism, as the main instrument of imperialism, we
 > have today neo-colonialism ... [which] like colonialism, is an
@@ -43,29 +41,25 @@ Stage of Imperialism* (1965), Kwame Nkrumah wrote:
 > increases, rather than decreases, the gap between the rich and the
 > poor countries of the world. The struggle against neo-colonialism is
 > not aimed at excluding the capital of the developed world from
-> operating in less developed countries. It is also dubious in
-> consideration of the name given being strongly related to the
-> concept of colonialism itself. It is aimed at preventing the
-> financial power of the developed countries being used in such a way
-> as to impoverish the less developed.
+> operating in less developed countries.
 
 So basically, if [colonialism](https://en.wikipedia.org/wiki/Colonialism) is Europeans bringing genocide, war,
 and religion to the Americas, neo-colonialism is the Americans (note
 the "n") bringing capitalism to the world.
 
-Before we see how this applies to the internet, but first we must make
-a detour into US history. This matters, because anyone would be
-hard-pressed to decouple neo-colonialism from the empire under which
-it evolves, and here we can only name the United States of America.
+Before we see how this applies to the internet, we must make a detour
+into US history. This matters, because anyone would be hard-pressed to
+decouple neo-colonialism from the empire under which it evolves, and
+here we can only name the United States of America.
 
 # US Declaration of independence
 
 Let's start with the [United States declaration of independence](https://en.wikipedia.org/wiki/United_States_Declaration_of_Independence)
 (1776). Many Americans may roll their eyes at this, possibly because
 that declaration is not actually part of the [US constitution](https://en.wikipedia.org/wiki/Constitution_of_the_United_States) and
-therefore may have questionable legal standing. I would argue,
-however, that it was a driving philosophical force in the founding of
-the nation. As Thomas Jefferson stated:
+therefore may have questionable legal standing. It was obviously a
+driving philosophical force in the founding of the nation. As its
+author, Thomas Jefferson, stated:
 
 > it was intended to be an expression of the American mind, and to
 > give to that expression the proper tone and spirit called for by the
@@ -85,46 +79,50 @@ has an impact in the sense that the above quote has been called an:
 > American Revolutionary period with the greatest "continuing
 > importance." ([Wikipedia](https://en.wikipedia.org/wiki/All_men_are_created_equal))
 
-Let's read that again: "all *men* are created equal". Already, at
-least half the human population will find a problem with this. Back
-when this was written, the US had slavery, women didn't had the right
-to vote, and therefore "Men" in that context was obviously limited to
-a certain number of "Men", namely "[property-owning or tax-paying
-white males, or about 6% of the population](https://en.wikipedia.org/wiki/Voting_rights_in_the_United_States#Milestones_of_national_franchise_changes)".
+Let's read that "immortal declaration" again: "all *men* are created
+equal". "Men", in that context, is limited to a certain number of
+people, namely "[property-owning or tax-paying white males, or about
+6% of the population](https://en.wikipedia.org/wiki/Voting_rights_in_the_United_States#Milestones_of_national_franchise_changes)". Back when this was written, women didn't
+have the right to vote, and slavery was legal. Jefferson himself owned
+hundreds of slaves.
 
-And if people might be tempted to say "well this is how things went
-back then, that's not colonialism, it's just we were moving slowly
-towards progress", let's take another example. The declaration was
-aimed at the [King](https://en.wikipedia.org/wiki/George_III_of_the_United_Kingdom) and was a [list of grievances](https://en.wikipedia.org/wiki/Grievances_of_the_United_States_Declaration_of_Independence). One of the
-concerns the colonists had was that the King:
+The declaration was aimed at the [King](https://en.wikipedia.org/wiki/George_III_of_the_United_Kingdom) and was a [list of
+grievances](https://en.wikipedia.org/wiki/Grievances_of_the_United_States_Declaration_of_Independence). A concern of the colonists was that the King:
 
 > has excited domestic insurrections amongst us, and has endeavoured
 > to bring on the inhabitants of our frontiers, the merciless Indian
 > Savages whose known rule of warfare, is an undistinguished
 > destruction of all ages, sexes and conditions.
 
-Here we see a clear mark of the [frontier myth](https://en.wikipedia.org/wiki/Frontier_myth) which paved the way
-for the US to exterminate and colonize the territory we now call the
+This is a clear mark of the [frontier myth](https://en.wikipedia.org/wiki/Frontier_myth) which paved the way for
+the US to exterminate and colonize the territory we now call the
 United States of America.
 
+As such, the declaration of independence is a colonial document,
+having being written by colonists. None of this is particularly
+surprising, historically, but I figured it serves as a good reminder
+of where we're coming from, since the Internet was born in the US.
+
 # A Declaration of the Independence of Cyberspace
 
 Two hundred and twenty years later, in 1996, [John Perry Barlow](https://en.wikipedia.org/wiki/John_Perry_Barlow_)
-wrote a [declaration of independence of cyberspace][declaration of independence of cyberspace]. Surely,
-hundreds of years later, we have abolished slavery, everyone has a
-right to vote (including women), we have made tremendous progress so
-this text will have aged better than the previous declaration it is
-obviously derived from? Let's see.
+wrote a [declaration of independence of cyberspace][declaration of independence of cyberspace].  At this
+point, ([almost](https://en.wikipedia.org/wiki/Voting_rights_in_the_United_States)) everyone has a right to vote (including women),
+slavery was abolished (although [some argue it still exists in the
+form of the prison system](https://en.wikipedia.org/wiki/Angela_Davis#Political_activism_and_speeches)); the US has made tremendous
+progress. So this text will have aged better than the previous
+declaration it is obviously derived from? Let's see.
 
 # The borders of independence
 
-One of the key theories that Barlow brings up is that: "*Cyberspace
-does not lie within your borders*". I am now immediately struck by the
-underlying frontier ideology here as well. In that sense, cyberspace
-is the [final frontier](https://en.wikipedia.org/wiki/Final_Frontier): having failed to colonize the moon,
-Americans turn inwards, deeper into technology. 
+One of the key ideas that Barlow brings up is that "*cyberspace does
+not lie within your borders*". In that sense, cyberspace is the [final
+frontier](https://en.wikipedia.org/wiki/Final_Frontier): having failed to colonize the moon, Americans turn
+inwards, deeper into technology, but still in the frontier
+ideology. And indeed, Barlow is one of the co-founder of the
+[Electronic Frontier Foundation](https://en.wikipedia.org/wiki/Electronic_Frontier_Foundation), which was founded 6 years prior.
 
-But there are other problems with that idea. As [Wikipedia quotes](https://en.wikipedia.org/wiki/A_Declaration_of_the_Independence_of_Cyberspace#Critical_response):
+But there are other problems with this idea. As [Wikipedia quotes](https://en.wikipedia.org/wiki/A_Declaration_of_the_Independence_of_Cyberspace#Critical_response):
 
 > The declaration has been criticized for internal
 > inconsistencies.[[9](https://web.archive.org/web/20161105174638/http://ieet.org/index.php/IEET/more/evans0220)] The declaration's assertion that
@@ -135,8 +133,8 @@ But there are other problems with that idea. As [Wikipedia quotes](https://en.wi
 And indeed, the internet is definitely a physical object. First
 controlled and severely restricted by "telcos" like AT&T, it was
 somewhat "liberated" from that monopoly in 1982 when an [anti-trust
-lawsuit](https://en.wikipedia.org/wiki/United_States_v._AT%26T) [broke up the monopoly](https://en.wikipedia.org/wiki/Breakup_of_the_Bell_System), a key historical event that
-made the internet possible. 
+lawsuit](https://en.wikipedia.org/wiki/United_States_v._AT%26T) [broke up the monopoly](https://en.wikipedia.org/wiki/Breakup_of_the_Bell_System), a key historical event that,
+one could argue, made the internet possible.
 
 (From there on, "backbone" providers could start competing and emerge,
 and eventually coalesce into new monopolies: Google has a monopoly on
@@ -161,22 +159,21 @@ But back to the Declaration:
 > grows itself through our collective actions.
 
 Here, we imply that "nature" is not a "public construction
-project". And indeed, the modern "nature" of development is
-private. Most of the internet is now privately owned and
-operated. Amazon hosts a majority of cloud content, and the rest is
-hosted by other large corporations. In Barlow's mind, the "public" is
-bad, and private is natural, it's good. It fails to take into account
-basic accountability principles that things like governments have been
-designed to address.
+project". And indeed, the modern "nature" of development is private:
+most of the internet is now privately owned and operated. Amazon hosts
+a majority of cloud content, and the rest is hosted by other large
+corporations. In Barlow's mind, the "public" is bad, and private is
+good, natural. This fails to consider basic accountability principles
+that things like governments have been designed to address, warts and
+all.
 
 I must admit that, as an anarchist, I loved that sentence when I read
-it. I was rooting for us, the underdogs, the revolutionary. And, in a

(Diff truncated)
finish final expansions, one more editing round to go
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index d7a88288..4170bf0a 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -314,19 +314,14 @@ hit-and-run programmers. Whenever any of those [fails](https://www.davidhaney.io
 [compromise](https://lwn.net/Articles/773121/) or bring down entire systems,
 
 This model of what is fundamentally "cheap labour" is spreading
-outwards from the internet. Delivery workers are being exploited (yet
-still [organise and fight](https://www.curbed.com/article/nyc-delivery-workers.html)) to the bone by apps like Uber and
-Doordash. Amazon warehouses are {...}
-
-https://www.politico.eu/article/coronavirus-amazon-employees-rage/
-
-{come about full circle}
-
-{expand?}
-{mechanical turk? blockchain and libertarians?}
-https://themargins.substack.com/p/doordash-and-pizza-arbitrage
-https://www.nytimes.com/2021/05/17/technology/apple-china-censorship-data.html
-
+outwards from the internet. Delivery workers are being exploitedto the
+bone by apps like Uber and Doordash (although they still [organise and
+fight back](https://www.curbed.com/article/nyc-delivery-workers.html)). Amazon workers are similarly exploited beyond belief,
+being forbidden to take breaks so much that they [pee in bottles](https://www.businessinsider.com/amazon-warehouse-workers-have-to-pee-into-bottles-2018-4),
+with [ambulances nearby to carry out the bodies](https://www.nytimes.com/2015/08/16/technology/inside-amazon-wrestling-big-ideas-in-a-bruising-workplace.html). During peak
+COVID-19, workers were being [dangerously exposed to the virus](https://www.politico.eu/article/coronavirus-amazon-employees-rage/) in
+warehouses. All this while Amazon is basically taking over [key
+aspects of the economy](https://www.vice.com/en/article/7xpgvx/amazons-is-trying-to-control-the-underlying-infrastructure-of-our-economy).
 
 # The colonial internet
 

extra quotes
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index 9d8ee161..d7a88288 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -239,8 +239,6 @@ its users. Facebook also spends three more times moderating on "brand
 safety", which again shows its priority is not the safety of its
 users, but of the advertisers.
 
-{...?}
-
 # The military internet
 
 [Sergey Brin](https://en.wikipedia.org/wiki/Sergey_Brin) and [Larry Page](https://en.wikipedia.org/wiki/Larry_Page) are the [Lewis and Clark](https://en.wikipedia.org/wiki/Lewis_and_Clark_Expedition) of
@@ -274,7 +272,21 @@ contracts all the time.
 
 # The "spreading" of the Internet
 
-{intro?}
+I am obviously not the first to identify colonial structures in the
+Internet. In an article titled [The Internet as an Extension of
+Colonialism](https://thesecuritydistillery.org/all-articles/the-internet-as-an-extension-of-colonialism), Heather McDonald correctly identifies fundamental
+problems with the "development" of new "markets" of internet
+consumers, primarily arguing that it creates a [digital divide](https://en.wikipedia.org/wiki/Digital_divide)
+which creates a "lack of agency and individual freedom":
+
+> Many African people have gained access to these technologies but not
+> the freedom to develop content such as web pages or social media
+> platforms in their own way. Digital natives have much more power and
+> therefore use this to create their own space with their own norms,
+> shaping their online world according to their own outlook.
+
+Interestingly, the spread of the aforementioned "social contract" was
+prophesized by Barlow in the Declaration:
 
 > This governance will arise according to the conditions of our
 > world, not yours. Our world is different.
@@ -298,29 +310,108 @@ an elite force of white men with obviously too much time on their
 hands (and also: no children). The mythical writing of GCC and Emacs
 by Richard Stallman is a good example of this, but the entirety of the
 internet now seems to be running on random bits and pieces running by
-hit-and-run programmers. Whenever any of those disappears, it can
-bring down entire systems. {left-pad}
+hit-and-run programmers. Whenever any of those [fails](https://www.davidhaney.io/npm-left-pad-have-we-forgotten-how-to-program/), it can
+[compromise](https://lwn.net/Articles/773121/) or bring down entire systems,
 
-With companies like Uber and Doordash [exploiting workers](https://www.curbed.com/article/nyc-delivery-workers.html) in
-despicable conditions, we have achieved a full circle and returned the
-favor, except that those people are trying to make a living out of
-that model, and typically failing.
+This model of what is fundamentally "cheap labour" is spreading
+outwards from the internet. Delivery workers are being exploited (yet
+still [organise and fight](https://www.curbed.com/article/nyc-delivery-workers.html)) to the bone by apps like Uber and
+Doordash. Amazon warehouses are {...}
 
-The internet is, if not neo-colonial, plain colonial. The US colonies
-had cotton fields and slaves, we have [disposable cell phones](https://www.jacobinmag.com/2015/03/smartphone-usage-technology-aschoff/) and
-[Foxconn workers](https://www.theguardian.com/technology/2017/jun/18/foxconn-life-death-forbidden-city-longhua-suicide-apple-iphone-brian-merchant-one-device-extract).
+https://www.politico.eu/article/coronavirus-amazon-employees-rage/
+
+{come about full circle}
 
+{expand?}
+{mechanical turk? blockchain and libertarians?}
 https://themargins.substack.com/p/doordash-and-pizza-arbitrage
 https://www.nytimes.com/2021/05/17/technology/apple-china-censorship-data.html
 
-{mechanical turk? blockchain and libertarians?}
 
-{missing refs to atlantic and security distillery articles}
+# The colonial internet
+
+The internet is, if not neo-colonial, plain colonial. The US colonies
+had cotton fields and slaves, we have [disposable cell phones](https://www.jacobinmag.com/2015/03/smartphone-usage-technology-aschoff/) and
+[Foxconn workers](https://www.theguardian.com/technology/2017/jun/18/foxconn-life-death-forbidden-city-longhua-suicide-apple-iphone-brian-merchant-one-device-extract). Canada has its [cultural genocide](https://www.thecanadianencyclopedia.ca/en/article/genocide-and-indigenous-peoples-in-canada), Facebook
+has some in [Ethiopia](https://www.vice.com/en_us/article/xg897a/hate-speech-on-facebook-is-pushing-ethiopia-dangerously-close-to-a-genocide), [Myanmar](https://www.salon.com/2020/08/20/facebook-is-a-global-threat-to-public-health-avaaz-report-says/), and mob violence in
+[India](https://www.buzzfeednews.com/article/pranavdixit/whatsapp-destroyed-village-lynchings-rainpada-india). Apple is at least implicitly acepting the [Uyghur
+genocide](https://en.wikipedia.org/wiki/Uyghur_genocide).
 
-{actual end}
+The Declaration actually ends like this:
 
 > We will create a civilization of the Mind in Cyberspace. May it be
 > more humane and fair than the world your governments have made
 > before.
 
+I kind of feel bad going through Barlow's declaration like this, point
+by point. It is somewhat unfair. But then again, he himself recognized
+he was a bit too "optimistic" in 2009, saying "We all get older and
+smarter" and also:
+
+> I'm an optimist. In order to be libertarian, you have to be an
+> optimist. You have to have a benign view of human nature, to believe
+> that human beings left to their own devices are basically good. But
+> I'm not so sure about human institutions, and I think the real point
+> of argument here is whether or not large corporations are human
+> institutions or some other entity we need to be thinking about
+> curtailing. Most libertarians are worried about government but not
+> worried about business. I think we need to be worrying about
+> business in exactly the same way we are worrying about government.
+
+In any case, we have a lot of work to do if we are to decolonize the
+internet. For me the first step is writing this to decolonize my own
+mind and see what the next steps might be. Taking apart the tech
+giants might be an important step, but we have to do a culture shift
+as well, and that's the hard part.
+
+# Appendix: further reading
+
+Here is another article that almost has the same title as mine:
+[Facebook and the New Colonialism](https://www.theatlantic.com/technology/archive/2016/02/facebook-and-the-new-colonialism/462393/). (Interestingly, the `<title>`
+tag on the article is actually "Facebook the Colonial Empire" which I
+also find interesting.) The article is worth reading in full, but I
+absolutely loved this quote:
+
+> Representations of colonialism have long been present in digital
+> landscapes. (“Even Super Mario Brothers,” the video game designer
+> Steven Fox told me last year. “You run through the landscape, stomp
+> on everything, and raise your flag at the end.”) But web-based
+> colonialism is not an abstraction. The online forces that shape a
+> new kind of imperialism go beyond Facebook.
+
+It goes on:
+
+> Consider, for example, digitization projects that focus primarily on
+> English-language literature. If the web is meant to be humanity’s new
+> Library of Alexandria, a living repository for all of humanity’s
+> knowledge, this is a problem. So is the fact that the vast majority of
+> Wikipedia pages are about a relatively tiny square of the planet. For
+> instance, 14 percent of the world’s population lives in Africa, but
+> less than 3 percent of the world’s geotagged Wikipedia articles
+> originate there, according to a 2014 Oxford Internet Institute
+> report.
+
+And they introduce another definition of Neo-colonialism:
+
+> “I’m loath to toss around words like colonialism but it’s hard to
+> ignore the family resemblances and recognizable DNA, to wit,” said
+> Deepika Bahri, an English professor at Emory University who focuses
+> on postcolonial studies. In an email, Bahri summed up those
+> similarities in list form:
+> 
+>     1. ride in like the savior
+> 
+>     2. bandy about words like equality, democracy, basic rights
+> 
+>     3. mask the long-term profit motive (see 2 above)
+> 
+>     4. justify the logic of partial dissemination as better than nothing
+> 
+>     5. partner with local elites and vested interests
+> 
+>     6. accuse the critics of ingratitude 
+> 
+> “In the end,” she told me, “if it isn’t a duck, it shouldn’t quack
+> like a duck.”
+
 [[!tag draft]]

more refs
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index 1278130d..9d8ee161 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -315,6 +315,8 @@ https://www.nytimes.com/2021/05/17/technology/apple-china-censorship-data.html
 
 {mechanical turk? blockchain and libertarians?}
 
+{missing refs to atlantic and security distillery articles}
+
 {actual end}
 
 > We will create a civilization of the Mind in Cyberspace. May it be

rephrase
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index e01ba32a..1278130d 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -286,15 +286,11 @@ absolutism, sexism, corporatism, and exploitation ethics, are now
 exploding outside of the Internet and into the real world.
 
 That's because the Internet is part of the world, it is both being
-changed by it and changing it. The Declaration ends with this
+changed by it and changing it. The Declaration ends (almost) with this
 prophetic note:
 
 > We will spread ourselves across the Planet so that no one can arrest
 > our thoughts.
->
-> We will create a civilization of the Mind in Cyberspace. May it be
-> more humane and fair than the world your governments have made
-> before.
 
 This prediction, now, feels chilling. The internet was built with free
 software which, fundamentally, was based on quasi-volunteer labour of
@@ -319,4 +315,10 @@ https://www.nytimes.com/2021/05/17/technology/apple-china-censorship-data.html
 
 {mechanical turk? blockchain and libertarians?}
 
+{actual end}
+
+> We will create a civilization of the Mind in Cyberspace. May it be
+> more humane and fair than the world your governments have made
+> before.
+
 [[!tag draft]]

toc, headings, notes
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
index f11e4dd2..e01ba32a 100644
--- a/blog/2021-10-23-neo-colonial-internet.md
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -1,5 +1,9 @@
 [[!meta title="The Neo-Colonial Internet"]]
 
+> This article is a draft and still needs to be completed.
+
+[[!toc]]
+
 Having been born in the previous millennia, I grew up with the
 Internet and the [declaration of independence of cyberspace][]. The
 ethics and politics of the Internet have always been important in my
@@ -112,7 +116,7 @@ right to vote (including women), we have made tremendous progress so
 this text will have aged better than the previous declaration it is
 obviously derived from? Let's see.
 
-## The borders of independence
+# The borders of independence
 
 One of the key theories that Barlow brings up is that: "*Cyberspace
 does not lie within your borders*". I am now immediately struck by the
@@ -148,7 +152,7 @@ latest 3900 mile undersea cable](https://www.cnet.com/tech/google-finishes-3900-
 South Africa or New Zealand, it connects the US to UK and
 Spain. Hardly a revolutionary prospect.
 
-## The Private Internet
+# The Private Internet
 
 But back to the Declaration:
 
@@ -174,7 +178,7 @@ to establish that independence and put too much trust in private
 companies. In retrospect, of course, it is obvious, but it was not, 30
 years ago.
 
-## The Social Contract
+# The Social Contract
 
 Here's another claim of the Declaration:
 
@@ -310,6 +314,9 @@ The internet is, if not neo-colonial, plain colonial. The US colonies
 had cotton fields and slaves, we have [disposable cell phones](https://www.jacobinmag.com/2015/03/smartphone-usage-technology-aschoff/) and
 [Foxconn workers](https://www.theguardian.com/technology/2017/jun/18/foxconn-life-death-forbidden-city-longhua-suicide-apple-iphone-brian-merchant-one-device-extract).
 
+https://themargins.substack.com/p/doordash-and-pizza-arbitrage
+https://www.nytimes.com/2021/05/17/technology/apple-china-censorship-data.html
+
 {mechanical turk? blockchain and libertarians?}
 
 [[!tag draft]]

first draft of my thoughts on the neo-colonial internet
diff --git a/blog/2021-10-23-neo-colonial-internet.md b/blog/2021-10-23-neo-colonial-internet.md
new file mode 100644
index 00000000..f11e4dd2
--- /dev/null
+++ b/blog/2021-10-23-neo-colonial-internet.md
@@ -0,0 +1,315 @@
+[[!meta title="The Neo-Colonial Internet"]]
+
+Having been born in the previous millennia, I grew up with the
+Internet and the [declaration of independence of cyberspace][]. The
+ethics and politics of the Internet have always been important in my
+life, but I have also been involved at other political levels,
+[against police brutality](https://cobp.resist.ca/), for [Food, Not Bombs](https://foodnotbombs.net/), [worker
+autonomy][koumbit], [software freedom](https://www.debian.org/), etc. For a long time, those
+things seem to be coherent and cohesive: it made sense.
+
+[koumbit]: https://www.koumbit.org/
+[declaration of independence of cyberspace]: https://www.eff.org/cyberspace-independence
+
+But the more I look at the modern internet -- and the large
+corporations that control it -- and the less confidence I have in my
+original political analysis of the liberating potential of
+technology. I have come to believe that most of our technological
+development is harmful to the large majority of the population of the
+planet, and of course the rest of the biosphere. And not only this, I
+have the feeling this has been a problem all along.
+
+This is because the Internet is a neo-colonial device, and has been
+from the start. Let me explain.
+
+# What is Neo-Colonialism?
+
+The term "[neo-colonialism](https://en.wikipedia.org/wiki/Neocolonialism)" was coined by [Kwame Nkrumah](https://en.wikipedia.org/wiki/Kwame_Nkrumah),
+first president of [Ghana](https://en.wikipedia.org/wiki/Ghana) (1960–66). In *Neo-Colonialism, the Last
+Stage of Imperialism* (1965), Kwame Nkrumah wrote:
+
+> In place of colonialism, as the main instrument of imperialism, we
+> have today neo-colonialism ... [which] like colonialism, is an
+> attempt to export the social conflicts of the capitalist
+> countries. ...
+>
+> The result of neo-colonialism is that foreign capital is used for
+> the exploitation rather than for the development of the less
+> developed parts of the world. Investment, under neo-colonialism,
+> increases, rather than decreases, the gap between the rich and the
+> poor countries of the world. The struggle against neo-colonialism is
+> not aimed at excluding the capital of the developed world from
+> operating in less developed countries. It is also dubious in
+> consideration of the name given being strongly related to the
+> concept of colonialism itself. It is aimed at preventing the
+> financial power of the developed countries being used in such a way
+> as to impoverish the less developed.
+
+So basically, if [colonialism](https://en.wikipedia.org/wiki/Colonialism) is Europeans bringing genocide, war,
+and religion to the Americas, neo-colonialism is the Americans (note
+the "n") bringing capitalism to the world.
+
+Before we see how this applies to the internet, but first we must make
+a detour into US history. This matters, because anyone would be
+hard-pressed to decouple neo-colonialism from the empire under which
+it evolves, and here we can only name the United States of America.
+
+# US Declaration of independence
+
+Let's start with the [United States declaration of independence](https://en.wikipedia.org/wiki/United_States_Declaration_of_Independence)
+(1776). Many Americans may roll their eyes at this, possibly because
+that declaration is not actually part of the [US constitution](https://en.wikipedia.org/wiki/Constitution_of_the_United_States) and
+therefore may have questionable legal standing. I would argue,
+however, that it was a driving philosophical force in the founding of
+the nation. As Thomas Jefferson stated:
+
+> it was intended to be an expression of the American mind, and to
+> give to that expression the proper tone and spirit called for by the
+> occasion
+
+In that aging document, we find the following pearl:
+
+> We hold these truths to be self-evident, that all men are created
+> equal, that they are endowed by their Creator with certain
+> unalienable Rights, that among these are Life, Liberty and the
+> pursuit of Happiness.
+
+I would therefore also argue that, as a founding document, it still
+has an impact in the sense that the above quote has been called an:
+
+> "immortal declaration", and "perhaps [the] single phrase" of the
+> American Revolutionary period with the greatest "continuing
+> importance." ([Wikipedia](https://en.wikipedia.org/wiki/All_men_are_created_equal))
+
+Let's read that again: "all *men* are created equal". Already, at
+least half the human population will find a problem with this. Back
+when this was written, the US had slavery, women didn't had the right
+to vote, and therefore "Men" in that context was obviously limited to
+a certain number of "Men", namely "[property-owning or tax-paying
+white males, or about 6% of the population](https://en.wikipedia.org/wiki/Voting_rights_in_the_United_States#Milestones_of_national_franchise_changes)".
+
+And if people might be tempted to say "well this is how things went
+back then, that's not colonialism, it's just we were moving slowly
+towards progress", let's take another example. The declaration was
+aimed at the [King](https://en.wikipedia.org/wiki/George_III_of_the_United_Kingdom) and was a [list of grievances](https://en.wikipedia.org/wiki/Grievances_of_the_United_States_Declaration_of_Independence). One of the
+concerns the colonists had was that the King:
+
+> has excited domestic insurrections amongst us, and has endeavoured
+> to bring on the inhabitants of our frontiers, the merciless Indian
+> Savages whose known rule of warfare, is an undistinguished
+> destruction of all ages, sexes and conditions.
+
+Here we see a clear mark of the [frontier myth](https://en.wikipedia.org/wiki/Frontier_myth) which paved the way
+for the US to exterminate and colonize the territory we now call the
+United States of America.
+
+# A Declaration of the Independence of Cyberspace
+
+Two hundred and twenty years later, in 1996, [John Perry Barlow](https://en.wikipedia.org/wiki/John_Perry_Barlow_)
+wrote a [declaration of independence of cyberspace][declaration of independence of cyberspace]. Surely,
+hundreds of years later, we have abolished slavery, everyone has a
+right to vote (including women), we have made tremendous progress so
+this text will have aged better than the previous declaration it is
+obviously derived from? Let's see.
+
+## The borders of independence
+
+One of the key theories that Barlow brings up is that: "*Cyberspace
+does not lie within your borders*". I am now immediately struck by the
+underlying frontier ideology here as well. In that sense, cyberspace
+is the [final frontier](https://en.wikipedia.org/wiki/Final_Frontier): having failed to colonize the moon,
+Americans turn inwards, deeper into technology. 
+
+But there are other problems with that idea. As [Wikipedia quotes](https://en.wikipedia.org/wiki/A_Declaration_of_the_Independence_of_Cyberspace#Critical_response):
+
+> The declaration has been criticized for internal
+> inconsistencies.[[9](https://web.archive.org/web/20161105174638/http://ieet.org/index.php/IEET/more/evans0220)] The declaration's assertion that
+> 'cyberspace' is a place removed from the physical world has also
+> been challenged by people who point to the fact that the internet is
+> always linked to its underlying geography.[[10](https://doi.org/10.1111%2Fgeoj.12009<)]
+
+And indeed, the internet is definitely a physical object. First
+controlled and severely restricted by "telcos" like AT&T, it was
+somewhat "liberated" from that monopoly in 1982 when an [anti-trust
+lawsuit](https://en.wikipedia.org/wiki/United_States_v._AT%26T) [broke up the monopoly](https://en.wikipedia.org/wiki/Breakup_of_the_Bell_System), a key historical event that
+made the internet possible. 
+
+(From there on, "backbone" providers could start competing and emerge,
+and eventually coalesce into new monopolies: Google has a monopoly on
+search and advertistement, Facebook on communications for a few
+generations, Amazon on storage and compute, Microsoft on hardware,
+etc. Even AT&T is now pretty much as consolidated as it was
+before.)
+
+The point is: all those companies have gigantic data centers and
+intercontinental cables. And those are definitely prioritizing the
+western world, the heart of the empire. To take an example, [Google's
+latest 3900 mile undersea cable](https://www.cnet.com/tech/google-finishes-3900-mile-subsea-cable-connecting-us-to-uk-and-spain/) does not connect Argentina to
+South Africa or New Zealand, it connects the US to UK and
+Spain. Hardly a revolutionary prospect.
+
+## The Private Internet
+
+But back to the Declaration:
+
+> Do not think that you can build it, as though it were a public
+> construction project. You cannot. It is an act of nature and it
+> grows itself through our collective actions.
+
+Here, we imply that "nature" is not a "public construction
+project". And indeed, the modern "nature" of development is
+private. Most of the internet is now privately owned and
+operated. Amazon hosts a majority of cloud content, and the rest is
+hosted by other large corporations. In Barlow's mind, the "public" is
+bad, and private is natural, it's good. It fails to take into account
+basic accountability principles that things like governments have been
+designed to address.
+
+I must admit that, as an anarchist, I loved that sentence when I read
+it. I was rooting for us, the underdogs, the revolutionary. And, in a
+way, I still do: I am still on the board of [Koumbit][] and work for a
+[non-profit](https://www.torproject.org/) that has pivoted towards censorship and surveillance
+evasion. Yet I cannot help but think that, as a whole, we have failed
+to establish that independence and put too much trust in private
+companies. In retrospect, of course, it is obvious, but it was not, 30
+years ago.
+
+## The Social Contract
+
+Here's another claim of the Declaration:
+
+> We are forming our own Social Contract.
+
+I remember the early days, back when "[netiquette](https://en.wikipedia.org/wiki/Etiquette_in_technology#Netiquette)" was a word, it
+felt that we had some sort of a contract. Not written in standards of
+course -- or barely (see [RFC1855](https://datatracker.ietf.org/doc/html/rfc1855)) -- but as a tacit
+agreement. How wrong we were. One just needs to look at Facebook to
+see how problematic that idea is on a global network.
+
+Facebook is the quintessential "hacker" ideology put in practice. Mark
+Zuckerberg [explicitly refused](https://www.theguardian.com/technology/2020/may/28/zuckerberg-facebook-police-online-speech-trump) to be "arbiter of truth" which
+implicitly means it will let lies take over its platforms. 
+
+He also sees Facebook as place where everyone is equal, something
+that's also echoed in the Declaration:

(Diff truncated)
mention microled
diff --git a/hardware/monitor.mdwn b/hardware/monitor.mdwn
index c32cf248..f23cadfc 100644
--- a/hardware/monitor.mdwn
+++ b/hardware/monitor.mdwn
@@ -63,6 +63,13 @@ See also this discussion:
 
 See the selector: https://www.tftcentral.co.uk/selector.htm
 
+Update, 2021-10-18: One thing to keep in mind while reviewing this is
+that the technology is changing rapidly in this space. The new MacBook
+M1 Pro ships with [MiniLED](https://en.wikipedia.org/wiki/MicroLED) which is like OLED (so real blacks,
+faster refresh rate, HDR, low energy consumption) but no burn-in,
+which is really amazing. Not yet available for real monitors, but
+might be waiting for.
+
 Full gamut
 ----------
 

update status
diff --git a/services/upgrades/bullseye.mdwn b/services/upgrades/bullseye.mdwn
index 98899819..6192fd1e 100644
--- a/services/upgrades/bullseye.mdwn
+++ b/services/upgrades/bullseye.mdwn
@@ -7,10 +7,10 @@ to upgrade slightly before or during the freeze. This time I feel
 almost late because it seems we'll be releasing in almost a month now
 (May 2021, it's April 2021 now).
 
-Update: and that procedure was done only on one workstation
+Update: this procedure was tested first on my workstation
 ([[hardware/curie]]). I have done another (the laptop,
 [[hardware/angela]]) in July 2021, and the server
-([[hardware/server/marcos]]) is still pending.
+([[hardware/server/marcos]]) in October 2021.
 
 This document contains my upgrade procedure, notable changes in the
 new version, issues I have stumbled upon (and possibly fixed), and

marcos upgraded, rainloop missing
diff --git a/services/upgrades/bullseye.mdwn b/services/upgrades/bullseye.mdwn
index b50d0098..98899819 100644
--- a/services/upgrades/bullseye.mdwn
+++ b/services/upgrades/bullseye.mdwn
@@ -269,6 +269,8 @@ list.
    testing, seems like it is in bad shape
  * [qalculate-gtk](https://tracker.debian.org/pkg/qalculate-gtk), my dearest calculator, was dropped from testing
    too! a team picked up the package, but too late it seems :/
+ * [rainloop](https://tracker.debian.org/pkg/rainloop), my webmail, [was removed](https://bugs.debian.org/972570) because of a dependency
+   problem, likely to get fixed in backports
  * usbguard-applet-qt - [removed 0.7.5](https://tracker.debian.org/news/1069337/accepted-usbguard-075ds-1-source-into-unstable/) from [usbguard](https://tracker.debian.org/pkg/usbguard),
    workaround: find the device ID in `lsbusb` and run `usbguard
    allow-device id $ID`

ikiwiki upgrade
diff --git a/services/wiki.mdwn b/services/wiki.mdwn
index 087211e2..9266fa38 100644
--- a/services/wiki.mdwn
+++ b/services/wiki.mdwn
@@ -131,7 +131,6 @@ On any given upgrade, the following patches need to be applied:
 
 I still carry those patches on top of ikiwiki:
 
- * [todo/git-annex_support](https://ikiwiki.info/todo/git-annex_support)
  * [todo/allow_toc_to_skip_entries](https://ikiwiki.info/todo/allow_toc_to_skip_entries)
  * [todo/include_page_variable_in_base_templates](https://ikiwiki.info/todo/include_page_variable_in_base_templates)
  * [bugs/javascript_resources_placed_after_html_tag](https://ikiwiki.info/bugs/javascript_resources_placed_after_html_tag/)
@@ -151,32 +150,29 @@ to follow the `$release` tag those patches are based on, to facilitate
 web-based reviews there.</div>
 
     cd src/ikiwiki &&
-    release=debian/3.20190228-1 &&
-    git rebase $release dev/git-annex-support &&
-    git diff $release..dev/git-annex-support | ( cd /usr/share/perl5 ; sudo patch -p1 --dry-run ) &&
-    git diff $release..dev/git-annex-support | ( cd /usr/share/perl5 ;    sudo patch -p1 ) &&
-    git rebase $release toc-skip &&
+    release=3.20200202.3 &&
+    git rebase --onto $release anarcat/master toc-skip &&
     git diff $release..toc-skip | ( cd /usr/share/perl5 ; sudo patch -p1 --dry-run ) &&
     git diff $release..toc-skip | ( cd /usr/share/perl5 ;    sudo patch -p1 ) &&
-    git rebase $release page-template-variable &&
+    git rebase --onto $release anarcat/master $release page-template-variable &&
     git diff $release..page-template-variable | ( cd /usr/share/perl5 ; sudo patch -p1 --dry-run ) &&
     git diff $release..page-template-variable | ( cd /usr/share/perl5 ;    sudo patch -p1 ) &&
-    git rebase $release js-newline &&
+    git rebase --onto $release anarcat/master $release js-newline &&
     git diff $release..js-newline | ( cd /usr/share/perl5 ; sudo patch -p1 --dry-run ) &&
     git diff $release..js-newline | ( cd /usr/share/perl5 ;    sudo patch -p1 ) &&
-    git rebase $release i18n-headinganchors &&
+    git rebase --onto $release anarcat/master $release i18n-headinganchors &&
     mv /usr/share/perl5/IkiWiki/Plugin/i18nheadinganchors.pm{,.orig} &&
     git diff $release..i18n-headinganchors | ( cd /usr/share/perl5 ; sudo patch -p1 --dry-run ) &&
     git diff $release..i18n-headinganchors | ( cd /usr/share/perl5 ; sudo patch -p1  ) &&
     diff -u /usr/share/perl5/IkiWiki/Plugin/i18nheadinganchors.pm{,.orig} &&
     rm /usr/share/perl5/IkiWiki/Plugin/i18nheadinganchors.pm.orig &&
+    git rebase --onto $release anarcat/master $release bootstrap-plugin &&
     mv /usr/share/perl5/IkiWiki/Plugin/bootstrap.pm{,.orig} &&
-    git rebase $release bootstrap-plugin &&
-    git diff $release..bootstrap-plugin | ( cd /usr/share/perl5 ; sudo patch -p1 --dry-run )
-    git diff $release..bootstrap-plugin | ( cd /usr/share/perl5 ; sudo patch -p1  )
+    git diff $release..bootstrap-plugin | ( cd /usr/share/perl5 ; sudo patch -p1 --dry-run ) &&
+    git diff $release..bootstrap-plugin | ( cd /usr/share/perl5 ; sudo patch -p1  ) &&
     diff -u /usr/share/perl5/IkiWiki/Plugin/bootstrap.pm{,.orig} &&
     rm /usr/share/perl5/IkiWiki/Plugin/bootstrap.pm.orig &&
-    git rebase $release admonitions &&
+    git rebase --onto $release anarcat/master $release admonitions &&
     mv /usr/share/perl5/IkiWiki/Plugin/admonition.pm{,.orig} &&
     git diff $release..admonitions IkiWiki/Plugin/admonition.pm | ( cd /usr/share/perl5 ; sudo patch -p1 --dry-run ) &&
     git diff $release..admonitions IkiWiki/Plugin/admonition.pm | ( cd /usr/share/perl5 ; sudo patch -p1 ) &&
@@ -185,6 +181,26 @@ web-based reviews there.</div>
     git diff $release..admonitions doc/style.css | ( cd /usr/share/ikiwiki/basewiki ; sudo patch -p2 --dry-run ) &&
     git diff $release..admonitions doc/style.css | ( cd /usr/share/ikiwiki/basewiki ; sudo patch -p2 )
 
+Then rebase and push all the branches:
+
+    for b in toc-skip page-template-variable'js-newline i18n-headinganchors bootstrap-plugin; do git co  $b && git reset --hard marcos/$b &&  git push --force-with-lease anarcat $b; done
+    git co deploy
+    git reset --hard $release
+    git merge toc-skip page-template-variable js-newline i18n-headinganchors bootstrap-plugin
+    git push --force-with-lease
+    git co master
+    git reset --hard $release
+    git push --force-with-lease anarcat
+
+## 2021-10-05: major upgrade (to bullseye)
+
+Upgraded the entire server to bullseye.
+
+The following patches were dropped:
+
+ * [todo/git-annex_support](https://ikiwiki.info/todo/git-annex_support)
+   (was not really working anyways)
+
 ## 2019-10-02: major upgrade
 
 Upgraded the entire server to buster. The following patches were

document the change required in unattended-upgrades
diff --git a/services/upgrades/bullseye.mdwn b/services/upgrades/bullseye.mdwn
index b5793e07..b50d0098 100644
--- a/services/upgrades/bullseye.mdwn
+++ b/services/upgrades/bullseye.mdwn
@@ -304,6 +304,10 @@ Also note that the *codename* of the security changed, this time, from
 APT configuration which involves pinning the `APT::Default-Release`
 manually.
 
+At least that's what the release notes say. In reality, in my case, I
+had the codename set in the unattended-upgrades configuration file,
+which required a change ([in Puppet](https://gitlab.com/anarcat/puppet/-/commit/f6bb076bab43e045b84e5c43a0a315025c8c21ee)).
+
 I can't find any other recent changes in my notes, but I could have
 sworn it's not the first time a change like this happens. If someone
 remember what it was *before* that, I would be grateful if I could

more info about printers
diff --git a/hardware/printer.md b/hardware/printer.md
index 445a7150..114bc381 100644
--- a/hardware/printer.md
+++ b/hardware/printer.md
@@ -16,3 +16,36 @@
 ## Must not have
 
  * ink-jet printing
+
+# Advice received
+
+ * avoid HP (twice), although one concern was with their "printing as
+   a service" approach with inkjet printer, which may not apply to me
+ * good words about Canon, which I have a personal chip on the
+   shoulder with
+ * don't expect scanning to work from Linux, instead scan to a SMB
+   share from the device (so look from SMB support)
+
+# Options
+
+Picking some common ratings websites (rtings.com and Wirecutters), I
+come to the following conclusion:
+
+ * HP has a more expensive model, but long-term per page cost is lower
+ * according to rtings.com, it's the opposite, the "Canon imageCLASS
+   MF743Cdw" has a better per-page cost
+ * according to rtings.com, it prints B&W faster, has a better
+   scanner, but worse photo printer, again than the MF743Cdw
+ * that said, the "Canon imageCLASS MF743Cdw" is not available at Best
+   Buy or Staples, the closest alternative at Staples is the MF741Cdw,
+   which doesn't have duplex scanning, but is cheaper (see [bh
+   comparison](https://www.bhphotovideo.com/c/compare/Canon_MF743Cdw_vs_Canon_MF644Cdw_vs_Canon_MF741Cdw/BHitems/1489652-REG_1489654-REG_1489653-REG)). it's out of stock at Staples and Bestbuy as well
+
+## HP Color LaserJet Pro MFP M479FDW
+
+<https://www.hp.com/us-en/shop/pdp/hp-color-laserjet-pro-mfp-m479fdw>
+
+recommended by Wirecutters and rtings.com
+
+ * [Staples](https://www.staples.ca/products/2946505-en-hp-color-laserjet-pro-mfp-m479dw-printer-w1a77abgj): CAD$699.99, [replacement B&W](https://www.staples.ca/products/24398984-en-hp-414a-w2020a-black-original-laserjet-toner-cartridge): 110$, 0.046$/page
+

start looking into printers
diff --git a/hardware/printer.md b/hardware/printer.md
new file mode 100644
index 00000000..445a7150
--- /dev/null
+++ b/hardware/printer.md
@@ -0,0 +1,18 @@
+# Requirements
+
+## Must have
+
+ * network port
+ * "driverless printing"
+ * laser
+ * stellar Linux support
+
+## Nice to have
+
+ * colors
+ * scanner/photocopier
+ * double-sided printing, AKA "[duplex printing](https://en.wikipedia.org/wiki/Duplex_printing)"
+
+## Must not have
+
+ * ink-jet printing

another good mbsync ref
diff --git a/blog/2021-06-29-another-mail-crash.md b/blog/2021-06-29-another-mail-crash.md
index 7a7edac6..1bb1b5a9 100644
--- a/blog/2021-06-29-another-mail-crash.md
+++ b/blog/2021-06-29-another-mail-crash.md
@@ -169,7 +169,7 @@ are other programs that sync mail. I'm looking at:
    switching from offlineimap to this, has support for TLS client
    certs, running over SSH (e.g. [presumably](https://www.angio.net/misc/mail.html) with `Tunnel "ssh -C
    -q imap.example.com /usr/lib/dovecot/imap"`), and generally has
-   good words from multiple Debian and notmuch people
+   good words from multiple Debian and notmuch people ([Arch tutorial](https://wiki.archlinux.org/title/Isync))
  * [getmail](http://pyropus.ca/software/getmail/): just downloads email, might not be enough
  * [nncp](http://www.nncpgo.org/): treat the local spool as another mail server, might not
    be compatible with my "multiple clients" setup

more evaluations of smd alternatives
diff --git a/blog/2021-06-29-another-mail-crash.md b/blog/2021-06-29-another-mail-crash.md
index b029895c..7a7edac6 100644
--- a/blog/2021-06-29-another-mail-crash.md
+++ b/blog/2021-06-29-another-mail-crash.md
@@ -167,8 +167,9 @@ are other programs that sync mail. I'm looking at:
    over SSH, see comment below
  * [isync/mbsync](http://isync.sf.net/): might be faster, I remember having trouble
    switching from offlineimap to this, has support for TLS client
-   certs, running over SSH, and generally has good words from multiple
-   Debian and notmuch people
+   certs, running over SSH (e.g. [presumably](https://www.angio.net/misc/mail.html) with `Tunnel "ssh -C
+   -q imap.example.com /usr/lib/dovecot/imap"`), and generally has
+   good words from multiple Debian and notmuch people
  * [getmail](http://pyropus.ca/software/getmail/): just downloads email, might not be enough
  * [nncp](http://www.nncpgo.org/): treat the local spool as another mail server, might not
    be compatible with my "multiple clients" setup
@@ -176,7 +177,8 @@ are other programs that sync mail. I'm looking at:
    using SSH to sync, <del>will try this next</del>, may have
    performance problems, see comment below
  * [interimap](https://guilhem.org/interimap/): syncs two IMAP servers, apparently faster than
-   `doveadm` and `offlineimap`
+   `doveadm` and `offlineimap`, but requires running an IMAP server
+   locally
  * [mail-sync](https://blog.hades.lkamp.de/mail-sync/): notify support, happens over any piped transport
    (e.g. ssh), diff/patch system, requires binary on both ends,
    mentions UUCP in the manpage, seems awfully complicated to setup,

also update TPO password manager, untested
diff --git a/.well-known/openpgpkey/Makefile b/.well-known/openpgpkey/Makefile
index 4d5eaa5b..a08a1d55 100644
--- a/.well-known/openpgpkey/Makefile
+++ b/.well-known/openpgpkey/Makefile
@@ -4,6 +4,7 @@ ADDRESS=anarcat@debian.org
 FINGERPRINT=8DC901CE64146C048AD50FBB792152527B75921E
 NEXT_EXPIRE=$(shell LANG=C date -d '+1 year +1 month' '+%Y-%m-%d')
 TPO_KEYRING=~/src/tor/account-keyring/
+TPO_PWMANAGER=~/src/tor/tor-passwords/
 
 all: warn hu upload
 
@@ -28,8 +29,15 @@ renew:
 	gpg --quick-set-expire $(FINGERPRINT) $(NEXT_EXPIRE)
 
 upload-tpo:
+	@echo "updating TPO keyring"
 	git -C $(TPO_KEYRING) pull
 	gpg --export --export-options export-minimal $(FINGERPRINT) > $(TPO_KEYRING)/torproject-keyring/anarcat-$(FINGERPRINT).gpg
 	git -C $(TPO_KEYRING) commit torproject-keyring/anarcat-$(FINGERPRINT).gpg
 	git -C $(TPO_KEYRING) push
 	git -C $(TPO_KEYRING) push alberti
+
+	@echo "updating TPO password manager keyring"
+	git -C $(TPO_PWMANAGER) pull
+	gpg --export --export-options export-minimal $(FINGERPRINT) | gpg --no-default-keyring --keyring=$(TPO_PWMANAGER)/.keyring --import
+	git -C $(TPO_PWMANAGER) commit .keyring
+	git -C $(TPO_PWMANAGER) push

response
diff --git a/blog/2021-09-05-bullseye-upgrade-notes/comment_2_f522f178bcc58f5dea201363c5ffa277._comment b/blog/2021-09-05-bullseye-upgrade-notes/comment_2_f522f178bcc58f5dea201363c5ffa277._comment
new file mode 100644
index 00000000..03dc681f
--- /dev/null
+++ b/blog/2021-09-05-bullseye-upgrade-notes/comment_2_f522f178bcc58f5dea201363c5ffa277._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="anarcat"
+ subject="""cssh and others"""
+ date="2021-09-21T14:57:58Z"
+ content="""
+Thanks Fabian, that's a great point! clusterssh (AKA `cssh`) is how I did a *lot* of Debian upgrades at Koumbit back in the days. I don't know why exactly I haven't used it yet here, but there's something to be said about heterogeneous systems here.
+
+If you have a lot of identical machines, then, yes, just batch-entering all those commands on all those machines at once works like a charm. I would actually use clustershell for this nowadays, since you can feed it a bunch of scripts more easily and you don't have to deal with tens of windows or Perl or TCL/TK like cssh (maybe I remember wrong).
+
+But still: that doesn't deal with the situation where you have that special snowflake server (e.g. PostgreSQL) that needs to be upgraded just so. Sure, you can do the upgrade at once there as well: you enter the magic commands on all the servers for that as well. But then if you mess it up, you destroy all your (e.g. PostgreSQL!) servers all at once.
+
+The idea of scripting this into something that can be batched by something like cumin or others is that you can start the upgrade on a part of the cluster and then *stop* if something goes wrong. With `cssh` and friends, it's kind of all-or-nothing.
+
+Of course, you can absolutely select part of the cluster by hand, but that is still kind of slow and manual.
+
+I want a silver bullet, and one that we can collaborate on too. If you or I can do cssh to deal with those things, that's great, but that doesn't help Roger over there who's just getting started with Debian sysadmin and has to now figure out how to upgrade PostgreSQL interactively...
+"""]]

approve comment
diff --git a/blog/2021-09-05-bullseye-upgrade-notes/comment_1_5c4a20ce8649253bcc96fac6d7296ae2._comment b/blog/2021-09-05-bullseye-upgrade-notes/comment_1_5c4a20ce8649253bcc96fac6d7296ae2._comment
new file mode 100644
index 00000000..2a27f40b
--- /dev/null
+++ b/blog/2021-09-05-bullseye-upgrade-notes/comment_1_5c4a20ce8649253bcc96fac6d7296ae2._comment
@@ -0,0 +1,31 @@
+[[!comment format=mdwn
+ ip="24.37.118.114"
+ claimedauthor="Fabian Rodriguez"
+ url="https://legoudulibre.com"
+ subject="clusterssh"
+ date="2021-09-21T02:22:24Z"
+ content="""
+I group together virtual machines, servers and containers that are similar.
+
+They tend to have configurations close enough to send the upgrade commands/ scripts in parallel, simultaneously.
+
+So for example I have a cluster of 3 Proxmox servers, I will access them with:
+
+    clusterssh pve01 pve02 pve03
+
+... and issue the commands there.
+
+Then for all the IS/IT servers (VMs):
+
+    clusterssh support syspass guacamole ssh-bastion
+
+And for web servers:
+
+    clusterssh web1 web2 web3 web4
+
+etc.
+
+It remains a semi-manual process but much faster than going into each and every system simultaneously. 
+
+I don't manage anything bigger than 15-20 servers at a time so it's not the same problem and probably wouldn't scale but it works for me.
+"""]]

Archival link:

The above link creates a machine-readable RSS feed that can be used to easily archive new changes to the site. It is used by internal scripts to do sanity checks on new entries in the wiki.

Created . Edited .