Recent changes to this wiki:

post
diff --git a/blog/entry/DIN.mdwn b/blog/entry/DIN.mdwn
index 668bba28..07be0f38 100644
--- a/blog/entry/DIN.mdwn
+++ b/blog/entry/DIN.mdwn
@@ -2,7 +2,8 @@
 
 My offgrid house has an industrial automation panel.
 
-[[!img pics/DIN/dinrail.jpg alt="A row of electrical devices, mounted on a
+[[!img pics/DIN/dinrail.jpg size=800x
+alt="A row of electrical devices, mounted on a
 metal rail. Many wires neatly extend from it above and below,
 disappearing into wire gutters."]]
 
@@ -23,11 +24,11 @@ stuff, and perhaps you could use a distraction too.
 The panel has my house's computer on it, as well as both AC and DC power
 distribution, breakers, and switching. Since the house is offgrid, the panel
 is designed to let every non-essential power drain be turned off, from
-my [[offgrid_fridge|fridge]] to the 20 terabytes of
+my [[offgrid_fridge|fridge_0.1]] to the 20 terabytes of
 [[offline_storage|usb_drives_with_no_phantom_load]] to the
 [[inverter|AIMS_inverter_control_via_GPIO_ports]] and satellite dish,
 the spring pump for my [[gravity_flow_water_system|hacking_water]], and
-even the outlet by the kitchen sink.
+even the power outlet by the kitchen sink.
 
 Saving power is part of why I'm using old-school relays and stuff and not
 IOT devices, the other reason is of course: IOT devices are horrible
@@ -62,12 +63,12 @@ clipped into place and it evolves for changing needs.
 
 Also, wire gutters, where have you been all my life?
 
-[[!img pics/DIN/gearwall.jpg size=500x 
-alt="A small utility room with an entire wall
+[[!img pics/DIN/gearwall.jpg size=600x 
+alt="A cramped utility room with an entire wall
 covered with electronic gear, including the DIN rail, which is surrounded by
 wire gutters"]]
-[[!img pics/DIN/wiregutter.jpg size=500x 
-alt="A wire gutter with the cover removed.
+[[!img pics/DIN/wiregutter.jpg size=300x 
+alt="Detail of a wire gutter with the cover removed.
 Numerous large and small wires run along it and exit here and there."]]
 
 Finally, if you'd like to know what everything on the DIN rail is, from
@@ -76,6 +77,4 @@ hub switch, computer switch, +24v block, -24v block, IO daughterboard, 1tb
 SSD, arm board, modem, 3 USB hubs, 5 relays, AC hot block, AC neutral
 block, DC-DC power converters, humidity sensor.
 
-[[!img pics/DIN/dinrailleft.jpg alt="DIN rail as described above, left side."]]
-[[!img pics/DIN/dinrailright.jpg alt="DIN rail as described above, right side."]]
-
+[[!img pics/DIN/dinrailfull.jpg size=900x alt="Full width of DIN rail."]]

add
diff --git a/blog/pics/DIN/dinrailfull.jpg b/blog/pics/DIN/dinrailfull.jpg
new file mode 100644
index 00000000..7e8954b6
Binary files /dev/null and b/blog/pics/DIN/dinrailfull.jpg differ

add
diff --git a/blog/pics/DIN/gearwall.jpg b/blog/pics/DIN/gearwall.jpg
new file mode 100644
index 00000000..d7c0e0cd
Binary files /dev/null and b/blog/pics/DIN/gearwall.jpg differ

add
diff --git a/blog/pics/DIN/dinrail.jpg b/blog/pics/DIN/dinrail.jpg
new file mode 100644
index 00000000..1c459569
Binary files /dev/null and b/blog/pics/DIN/dinrail.jpg differ

add
diff --git a/blog/entry/DIN.mdwn b/blog/entry/DIN.mdwn
index 0ab512d2..668bba28 100644
--- a/blog/entry/DIN.mdwn
+++ b/blog/entry/DIN.mdwn
@@ -1,20 +1,24 @@
+[[!meta title="DIN distractions"]]
+
 My offgrid house has an industrial automation panel.
 
-[[!img DIN/dinrail.jpg alt="A row of electrical devices, mounted on a
+[[!img pics/DIN/dinrail.jpg alt="A row of electrical devices, mounted on a
 metal rail. Many wires neatly extend from it above and below,
 disappearing into wire gutters."]]
 
 I started building this in February, before covid-19 was impacting us here,
-when lots of digikey orders were no big problem, and getting an unusual
+when lots of mail orders were no big problem, and getting an unusual
 3D-printed DIN rail bracket for a SSD was just a couple clicks.
 
-I finished a month deep into social isolation and quarentine, scrounging
-around the house for scrap wire, scavenging screws from unused stuff and
-cutting them to size, and hoping I would not end up in a "need just one
-more part" situation.
+I finished a month later, deep into social isolation and quarentine,
+scrounging around the house for scrap wire, scavenging screws from unused
+stuff and cutting them to size, and hoping I would not end up in a "need
+just one more part that I can't get" situation.
 
 It got rather elaborate, and working on it was often a welcome distraction
-from the news when I couldn't concentrate on my usual work.
+from the news when I couldn't concentrate on my usual work. I'm posting
+this now because people sometimes tell me they like hearing about my offfgrid
+stuff, and perhaps you could use a distraction too.
 
 The panel has my house's computer on it, as well as both AC and DC power
 distribution, breakers, and switching. Since the house is offgrid, the panel
@@ -25,30 +29,46 @@ my [[offgrid_fridge|fridge]] to the 20 terabytes of
 the spring pump for my [[gravity_flow_water_system|hacking_water]], and
 even the outlet by the kitchen sink.
 
-(Saving power is part of why I'm using old-school relays and stuff and not
-IOT devices, the other reason is of course: IOT devices are horrible.)
+Saving power is part of why I'm using old-school relays and stuff and not
+IOT devices, the other reason is of course: IOT devices are horrible
+dystopian e-waste. I'm taking the utopian Star Trek approach, where I
+can command "full power to the vacuum cleaner!"
 
-[[!img DIN/daughterboard.jpg alt="Two circuit boards, connected by numerous
+[[!img pics/DIN/daughterboard.jpg size=300x
+alt="Two circuit boards, connected by numerous
 ribbon cables, and clearly hand-soldered. The smaller board is suspended
 above the larger."]]
-[[!img DIN/schematic.jpg alt="An electrical schematic, of moderate complexity."]]
+[[!img pics/DIN/schematic.jpg size=600x alt="An electrical schematic, of moderate complexity."]]
 
 At the core of the panel, next to the cubietruck arm board, is a custom
 IO daughterboard. Designed and built by hand to fit into a DIN mount case,
 it uses every GPIO pin on the cubietruck's main GPIO header. Making
-this board was about half the project. It got pretty tight in there.
+this board took 40+ hours, and was about half the project. It got
+pretty tight in there.
+
+This was my first foray into DIN rail mount, and it really is industrial
+lego -- a whole universe of parts that all fit together and are immensely
+flexible. Often priced more than seems reasonable for a little bit of
+plastic and metal, until you look at the spec sheets and the ratings.
+(Total cost for my panel was $400.) It's odd that it's not more used
+outside its niche -- I came of age in the Bay Area, surrounded by rack
+mount equipment, but no DIN mount equipment. Hacking the hardware in
+a rack is unusual, but DIN *invites* hacking.
 
-This was my first forway into DIN rail mount, and it really is industrial
-lego -- a whole universe of parts that all fit together. This is a second
-system kind of project, replacing some unsightly shelves full of gear
-with something kind of overdone. But should be worth it in the long run
-as new gear gets clipped into place.
+Admittedly, this is a second system kind of project, replacing some
+unsightly shelves full of gear and wires everywhere with something kind
+of overdone. But should be worth it in the long run as new gear gets
+clipped into place and it evolves for changing needs.
 
 Also, wire gutters, where have you been all my life?
 
-[[!img DIN/gearwall.jpg alt="A small utility room with an entire wall
+[[!img pics/DIN/gearwall.jpg size=500x 
+alt="A small utility room with an entire wall
 covered with electronic gear, including the DIN rail, which is surrounded by
 wire gutters"]]
+[[!img pics/DIN/wiregutter.jpg size=500x 
+alt="A wire gutter with the cover removed.
+Numerous large and small wires run along it and exit here and there."]]
 
 Finally, if you'd like to know what everything on the DIN rail is, from
 left to right: Ground block, 24v DC disconnect, fridge GFI, spare GFI, USB
@@ -56,5 +76,6 @@ hub switch, computer switch, +24v block, -24v block, IO daughterboard, 1tb
 SSD, arm board, modem, 3 USB hubs, 5 relays, AC hot block, AC neutral
 block, DC-DC power converters, humidity sensor.
 
-[[!img DIN/dinrailleft.jpg alt="DIN rail as described above, left side."]]
-[[!img DIN/dinrailright.jpg alt="DIN rail as described above, right side."]]
+[[!img pics/DIN/dinrailleft.jpg alt="DIN rail as described above, left side."]]
+[[!img pics/DIN/dinrailright.jpg alt="DIN rail as described above, right side."]]
+
diff --git a/blog/pics/DIN/wiregutter.jpg b/blog/pics/DIN/wiregutter.jpg
new file mode 100644
index 00000000..53d41005
Binary files /dev/null and b/blog/pics/DIN/wiregutter.jpg differ

add
diff --git a/blog/entry/DIN.mdwn b/blog/entry/DIN.mdwn
new file mode 100644
index 00000000..0ab512d2
--- /dev/null
+++ b/blog/entry/DIN.mdwn
@@ -0,0 +1,60 @@
+My offgrid house has an industrial automation panel.
+
+[[!img DIN/dinrail.jpg alt="A row of electrical devices, mounted on a
+metal rail. Many wires neatly extend from it above and below,
+disappearing into wire gutters."]]
+
+I started building this in February, before covid-19 was impacting us here,
+when lots of digikey orders were no big problem, and getting an unusual
+3D-printed DIN rail bracket for a SSD was just a couple clicks.
+
+I finished a month deep into social isolation and quarentine, scrounging
+around the house for scrap wire, scavenging screws from unused stuff and
+cutting them to size, and hoping I would not end up in a "need just one
+more part" situation.
+
+It got rather elaborate, and working on it was often a welcome distraction
+from the news when I couldn't concentrate on my usual work.
+
+The panel has my house's computer on it, as well as both AC and DC power
+distribution, breakers, and switching. Since the house is offgrid, the panel
+is designed to let every non-essential power drain be turned off, from
+my [[offgrid_fridge|fridge]] to the 20 terabytes of
+[[offline_storage|usb_drives_with_no_phantom_load]] to the
+[[inverter|AIMS_inverter_control_via_GPIO_ports]] and satellite dish,
+the spring pump for my [[gravity_flow_water_system|hacking_water]], and
+even the outlet by the kitchen sink.
+
+(Saving power is part of why I'm using old-school relays and stuff and not
+IOT devices, the other reason is of course: IOT devices are horrible.)
+
+[[!img DIN/daughterboard.jpg alt="Two circuit boards, connected by numerous
+ribbon cables, and clearly hand-soldered. The smaller board is suspended
+above the larger."]]
+[[!img DIN/schematic.jpg alt="An electrical schematic, of moderate complexity."]]
+
+At the core of the panel, next to the cubietruck arm board, is a custom
+IO daughterboard. Designed and built by hand to fit into a DIN mount case,
+it uses every GPIO pin on the cubietruck's main GPIO header. Making
+this board was about half the project. It got pretty tight in there.
+
+This was my first forway into DIN rail mount, and it really is industrial
+lego -- a whole universe of parts that all fit together. This is a second
+system kind of project, replacing some unsightly shelves full of gear
+with something kind of overdone. But should be worth it in the long run
+as new gear gets clipped into place.
+
+Also, wire gutters, where have you been all my life?
+
+[[!img DIN/gearwall.jpg alt="A small utility room with an entire wall
+covered with electronic gear, including the DIN rail, which is surrounded by
+wire gutters"]]
+
+Finally, if you'd like to know what everything on the DIN rail is, from
+left to right: Ground block, 24v DC disconnect, fridge GFI, spare GFI, USB
+hub switch, computer switch, +24v block, -24v block, IO daughterboard, 1tb
+SSD, arm board, modem, 3 USB hubs, 5 relays, AC hot block, AC neutral
+block, DC-DC power converters, humidity sensor.
+
+[[!img DIN/dinrailleft.jpg alt="DIN rail as described above, left side."]]
+[[!img DIN/dinrailright.jpg alt="DIN rail as described above, right side."]]
diff --git a/blog/pics/DIN/daughterboard.jpg b/blog/pics/DIN/daughterboard.jpg
new file mode 100644
index 00000000..2444bfb1
Binary files /dev/null and b/blog/pics/DIN/daughterboard.jpg differ
diff --git a/blog/pics/DIN/schematic.jpg b/blog/pics/DIN/schematic.jpg
new file mode 100644
index 00000000..b9573d73
Binary files /dev/null and b/blog/pics/DIN/schematic.jpg differ

Request to add a --editor flag to vidir and make it understand file URIs
diff --git a/code/moreutils/discussion.mdwn b/code/moreutils/discussion.mdwn
index f6e621d6..f11410e3 100644
--- a/code/moreutils/discussion.mdwn
+++ b/code/moreutils/discussion.mdwn
@@ -274,6 +274,19 @@ It computes the number of days between two dates and can check whether a date ex
 
 ## vidir
 
+I hope this is the right place to make any propositions.
+Vidir is the, by far, most powerfull mass renaming tool I am aware of, but unfortunately it is limited to terminal use only.
+However, sometimes I want to do mass renaming from a graphical file browser, atm this is possible by opening the current folder in terminal and typing vidir.
+Many file browsers (e.g. nemo, nautilus, thunar) allow you to specify a command for mass renaming purposes which brings me to the following two limitations:
+
+* In most of these file-browsers the file names are given as URIs which vidir doesn't seem to understand
+
+* My EDITOR variable is, of course, set to vim therefore, it doesn't work from a graphical context.
+  It would be nice if vidir would understand a command line flag like --editor where one could set an editor (e.g. gvim) only for the current session
+
+-- Mani
+
+
 A suggestion regarding vidir:
 I would find it quite useful if vidir could work with version control system commands like:
 

Added a comment: Excited to try git-annex
diff --git a/blog/entry/how_I_maybe_didnt_burn_out/comment_6_cd08526d09c26cd14d984c06b9d0e21a._comment b/blog/entry/how_I_maybe_didnt_burn_out/comment_6_cd08526d09c26cd14d984c06b9d0e21a._comment
new file mode 100644
index 00000000..220a2245
--- /dev/null
+++ b/blog/entry/how_I_maybe_didnt_burn_out/comment_6_cd08526d09c26cd14d984c06b9d0e21a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="pannekoek"
+ avatar="http://cdn.libravatar.org/avatar/676a7c403af0627c9bde84ee1ab3975c"
+ subject="Excited to try git-annex"
+ date="2020-03-27T18:19:11Z"
+ content="""
+git-annex seems really cool! I'm one of those users who has large repository of source files I want to track with \"vanilla git\" and one subdirectory of very large files I want to manage with git-annex. Pardon me if this is mention elsewhere, but how can I set up git annex v7 to only annex files I explicitly \"git annex add\" and otherwise leave \"git add\" unchanged?
+
+Thanks for all of your hard work. Your many projects and experiments in off-grid living are an inspiration.
+"""]]

add
diff --git a/blog/entry/quarantimer.mdwn b/blog/entry/quarantimer.mdwn
new file mode 100644
index 00000000..8c15cac3
--- /dev/null
+++ b/blog/entry/quarantimer.mdwn
@@ -0,0 +1,34 @@
+[[!meta title="quarantimer: a coronovirus quarantine timer for your things"]]
+
+I am trying to avoid bringing coronovirus into my house on anything,
+and I also don't want to sterilize a lot of stuff. (Tedious and easy to
+make a mistake.) Currently it seems that the best approach is to leave
+stuff to sit undisturbed someplace safe for long enough for the virus to
+degrade away.
+
+Following that policy, I've quickly ended up with a porch full of stuff
+in different stages of quarantine, and I am quickly losing track of how
+long things have been in quarantine. If you have the same problem,
+here is a solution:
+
+<https://quarantimer.app/>
+
+Open it on your mobile device, and you can take photos of each thing,
+select the kind of surfaces it has, and it will track the quarantine time
+for you. You can share the link to other devices or other people to
+collaborate.
+
+[[!img code/quarantimer/screenshot.png]]
+
+I anticipate the javascript and css will improve, but it's good enough for
+now. I will provide this website until the crisis is over. Of course,
+it's free software and you can also host your own.
+
+If this seems useful, please tell your friends and family about it.
+
+Be well!
+
+----
+
+This is made possible by my supporters on
+[Patreon](https://patreon.com/joeyh/), particularly Jake Vosloo.

add
diff --git a/code.mdwn b/code.mdwn
index 9f54f1a2..ab93e7c5 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -22,6 +22,7 @@ The stuff that's swapped into my local cache at the moment.
 [[haskell-filepath-bytestring]]
 [[arduino-copilot]]
 [[virtual-hallway-track]]
+[[quarantimer]]
 
 ## Less active projects
 

add
diff --git a/code/quarantimer.mdwn b/code/quarantimer.mdwn
new file mode 100644
index 00000000..a0b9cdd8
--- /dev/null
+++ b/code/quarantimer.mdwn
@@ -0,0 +1,5 @@
+Coronavirus quarantine timer
+
+<https://quarantimer.app/>
+
+[[!img code/quarantimer/screenshot.png]]
diff --git a/code/quarantimer/screenshot.png b/code/quarantimer/screenshot.png
new file mode 100644
index 00000000..16b34d63
Binary files /dev/null and b/code/quarantimer/screenshot.png differ

screenshot
diff --git a/code/virtual-hallway-track.mdwn b/code/virtual-hallway-track.mdwn
index 80a17b16..4d82e05b 100644
--- a/code/virtual-hallway-track.mdwn
+++ b/code/virtual-hallway-track.mdwn
@@ -9,5 +9,6 @@ and has only been used in conjunction with one conference so far.
 
 [[!img screenshot.png size=640x]]
 
-
 [[!img screenshot2.png size=640x]]
+
+[[!img screenshot3.png size=640x]]
diff --git a/code/virtual-hallway-track/screenshot3.png b/code/virtual-hallway-track/screenshot3.png
new file mode 100644
index 00000000..3022e186
Binary files /dev/null and b/code/virtual-hallway-track/screenshot3.png differ

screenshot
diff --git a/code/virtual-hallway-track.mdwn b/code/virtual-hallway-track.mdwn
index bf4019f6..80a17b16 100644
--- a/code/virtual-hallway-track.mdwn
+++ b/code/virtual-hallway-track.mdwn
@@ -8,3 +8,6 @@ and has only been used in conjunction with one conference so far.
 <https://git.joeyh.name/index.cgi/virtual-hallway-track.git/>
 
 [[!img screenshot.png size=640x]]
+
+
+[[!img screenshot2.png size=640x]]
diff --git a/code/virtual-hallway-track/screenshot2.png b/code/virtual-hallway-track/screenshot2.png
new file mode 100644
index 00000000..82b5e4cc
Binary files /dev/null and b/code/virtual-hallway-track/screenshot2.png differ

scale
diff --git a/code/virtual-hallway-track.mdwn b/code/virtual-hallway-track.mdwn
index ea5c909e..bf4019f6 100644
--- a/code/virtual-hallway-track.mdwn
+++ b/code/virtual-hallway-track.mdwn
@@ -7,4 +7,4 @@ and has only been used in conjunction with one conference so far.
 
 <https://git.joeyh.name/index.cgi/virtual-hallway-track.git/>
 
-[[!img screenshot.png]]
+[[!img screenshot.png size=640x]]

Revert "scale"
This reverts commit 48d2182e6316a24dd7c57822d064070445f0ada3.
diff --git a/code/virtual-hallway-track/screenshot.png b/code/virtual-hallway-track/screenshot.png
index 5f663fda..751629bf 100644
Binary files a/code/virtual-hallway-track/screenshot.png and b/code/virtual-hallway-track/screenshot.png differ

scale
diff --git a/code/virtual-hallway-track/screenshot.png b/code/virtual-hallway-track/screenshot.png
index 751629bf..5f663fda 100644
Binary files a/code/virtual-hallway-track/screenshot.png and b/code/virtual-hallway-track/screenshot.png differ

update
diff --git a/offgrid/water.mdwn b/offgrid/water.mdwn
index 88c203a4..5516935b 100644
--- a/offgrid/water.mdwn
+++ b/offgrid/water.mdwn
@@ -8,8 +8,8 @@ the only way to get water pressure was a pump with a pressure tank. I did
 not like this system, which barely worked, was noisy every time the water
 ran, and once leaked all over the living room.
 
-I found a flat spot around 50 feet higher than the house, and have added a
-water tank there (currently a 50 gallon temporary drum). 
+I found a flat spot around 50 feet higher than the house, and installed
+two 550 gallon water tanks.
 
 Repurposing an old, small set of solar panels, and a Shurflow pump with a
 linear voltage regulator, I found it was able to pump water up there from
@@ -17,11 +17,13 @@ the cistern.
 
 The cistern was cleaned out, re-sealed and water level sensors installed,
 so it will slowly fill up from the spring and then the pump will periodically
-pump 100 gallons of water out of it.
+pump out of it.
 
 I hand buried around 300 feet of PEX pipe, 12 inches deep, to connect the
 water tank to the house, using a tool called a "whomper" which was easier
 than digging a trench by hand and refilling.
 
-The system works great, I have 30 PSI now and only need more water storage
-on the hill to complete it.
+The system works great, I have 30 PSI now, and sufficient storage to easily
+get through the fall dry season.
+
+For more see [[blog/entry/hacking_water]].

update
diff --git a/code/virtual-hallway-track.mdwn b/code/virtual-hallway-track.mdwn
index c313c3a4..ea5c909e 100644
--- a/code/virtual-hallway-track.mdwn
+++ b/code/virtual-hallway-track.mdwn
@@ -1,9 +1,10 @@
 The best part of a good conference is its hallway track,
-with conversations in small, shifting groups.
+with conversations in small groups that grow and split, and the chance to
+look around, find your friends and see what they're enthused about.
 
 This program tries to emulate that in a virtual space. It's experimental
 and has only been used in conjunction with one conference so far.
 
-[[!img screenshot.png]]
-
 <https://git.joeyh.name/index.cgi/virtual-hallway-track.git/>
+
+[[!img screenshot.png]]

vht
diff --git a/code.mdwn b/code.mdwn
index 38766cb0..9f54f1a2 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -21,6 +21,7 @@ The stuff that's swapped into my local cache at the moment.
 [[fridge0]]
 [[haskell-filepath-bytestring]]
 [[arduino-copilot]]
+[[virtual-hallway-track]]
 
 ## Less active projects
 
diff --git a/code/virtual-hallway-track.mdwn b/code/virtual-hallway-track.mdwn
new file mode 100644
index 00000000..c313c3a4
--- /dev/null
+++ b/code/virtual-hallway-track.mdwn
@@ -0,0 +1,9 @@
+The best part of a good conference is its hallway track,
+with conversations in small, shifting groups.
+
+This program tries to emulate that in a virtual space. It's experimental
+and has only been used in conjunction with one conference so far.
+
+[[!img screenshot.png]]
+
+<https://git.joeyh.name/index.cgi/virtual-hallway-track.git/>
diff --git a/code/virtual-hallway-track/screenshot.png b/code/virtual-hallway-track/screenshot.png
new file mode 100644
index 00000000..751629bf
Binary files /dev/null and b/code/virtual-hallway-track/screenshot.png differ

poll vote (watched it all, liked it)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index 61d1ad12..0c8af3a4 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 62 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 14 "not interested"]]
+[[!poll 63 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 14 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

poll vote (watched it all, liked it)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index 0d0b7766..61d1ad12 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 61 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 14 "not interested"]]
+[[!poll 62 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 14 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

poll vote (not interested)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index 4d025ef3..0d0b7766 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 61 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 16 "too haskell for me" 13 "not interested"]]
+[[!poll 61 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 14 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

poll vote (too haskell for me)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index e0ac7e02..4d025ef3 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 61 "watched it all, liked it" 9 "watched some, boring" 5 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 61 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 16 "too haskell for me" 13 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

poll vote (too long for me)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index 9d4b2460..e0ac7e02 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 61 "watched it all, liked it" 10 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 61 "watched it all, liked it" 9 "watched some, boring" 5 "too long for me" 15 "too haskell for me" 13 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

poll vote (watched some, boring)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index 873a99f0..9d4b2460 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 62 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 61 "watched it all, liked it" 10 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

poll vote (watched it all, liked it)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index a897950c..873a99f0 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 61 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 62 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

poll vote (I don't plan to try it)
diff --git a/code/kaxxt/feedback.mdwn b/code/kaxxt/feedback.mdwn
index 8f326b76..855ebca3 100644
--- a/code/kaxxt/feedback.mdwn
+++ b/code/kaxxt/feedback.mdwn
@@ -1,4 +1,4 @@
 Whatdayathink? Please vote in the poll, or post your
 experiences/questions to [[/code/Kaxxt/Discussion]].
 
-[[!poll 4 "I tried it, liked it." 0 "I tried it, needs work." 13 "I haven't tried it, but want to" 2 "I don't plan to try it"]]
+[[!poll 4 "I tried it, liked it." 0 "I tried it, needs work." 12 "I haven't tried it, but want to" 3 "I don't plan to try it"]]

poll vote (I haven't tried it, but want to)
diff --git a/code/kaxxt/feedback.mdwn b/code/kaxxt/feedback.mdwn
index 4c80decf..8f326b76 100644
--- a/code/kaxxt/feedback.mdwn
+++ b/code/kaxxt/feedback.mdwn
@@ -1,4 +1,4 @@
 Whatdayathink? Please vote in the poll, or post your
 experiences/questions to [[/code/Kaxxt/Discussion]].
 
-[[!poll 4 "I tried it, liked it." 1 "I tried it, needs work." 12 "I haven't tried it, but want to" 2 "I don't plan to try it"]]
+[[!poll 4 "I tried it, liked it." 0 "I tried it, needs work." 13 "I haven't tried it, but want to" 2 "I don't plan to try it"]]

poll vote (I tried it, needs work.)
diff --git a/code/kaxxt/feedback.mdwn b/code/kaxxt/feedback.mdwn
index 38745036..4c80decf 100644
--- a/code/kaxxt/feedback.mdwn
+++ b/code/kaxxt/feedback.mdwn
@@ -1,4 +1,4 @@
 Whatdayathink? Please vote in the poll, or post your
 experiences/questions to [[/code/Kaxxt/Discussion]].
 
-[[!poll 5 "I tried it, liked it." 0 "I tried it, needs work." 12 "I haven't tried it, but want to" 2 "I don't plan to try it"]]
+[[!poll 4 "I tried it, liked it." 1 "I tried it, needs work." 12 "I haven't tried it, but want to" 2 "I don't plan to try it"]]

poll vote (I tried it, liked it.)
diff --git a/code/kaxxt/feedback.mdwn b/code/kaxxt/feedback.mdwn
index 20b95675..38745036 100644
--- a/code/kaxxt/feedback.mdwn
+++ b/code/kaxxt/feedback.mdwn
@@ -1,4 +1,4 @@
 Whatdayathink? Please vote in the poll, or post your
 experiences/questions to [[/code/Kaxxt/Discussion]].
 
-[[!poll 4 "I tried it, liked it." 0 "I tried it, needs work." 12 "I haven't tried it, but want to" 2 "I don't plan to try it"]]
+[[!poll 5 "I tried it, liked it." 0 "I tried it, needs work." 12 "I haven't tried it, but want to" 2 "I don't plan to try it"]]

diff --git a/code/moreutils/discussion.mdwn b/code/moreutils/discussion.mdwn
index fc93bb8a..f6e621d6 100644
--- a/code/moreutils/discussion.mdwn
+++ b/code/moreutils/discussion.mdwn
@@ -1,6 +1,16 @@
 Feel free to edit this page to suggest tools to add, or make any other
 comments --[[Joey]]
 
+## tool suggestion: "re" (Reach Recent Folders)
+
+The `re` command aims to save numerous `cd` operations for reaching recently-used folders.
+This command orders folders by date of last modification, and enables specifying a substring
+of the name of the folder targeted. The `re` command saves me a lot of time, every single day.
+
+It is currently implemented as a shell script.
+https://github.com/charguer/re
+
+
 ## tool suggestion: "even" and "wol"
 
 Written these two tiny tools, but figure they're useful to others:

update for readfrom rename to input
diff --git a/blog/entry/announcing_arduino-copilot.mdwn b/blog/entry/announcing_arduino-copilot.mdwn
index 1ab90ba9..a80f8ad9 100644
--- a/blog/entry/announcing_arduino-copilot.mdwn
+++ b/blog/entry/announcing_arduino-copilot.mdwn
@@ -57,7 +57,7 @@ time, and then back to fast flashing.
 
 	main :: IO ()
 	main = arduino $ do
-	        buttonpressed <- readfrom pin12
+	        buttonpressed <- input pin12
 	        led =: buttonpressed || blinking
 	        delay =: MilliSeconds (longer_and_longer * 2)
 
@@ -93,7 +93,7 @@ without ever generating C code, right at the console!
 But first, one line of code needs to be changed, to provide some button states
 for the simulation:
 
-	        buttonpressed <- readfrom' pin12 [False, False, False, True, True]
+	        buttonpressed <- input' pin12 [False, False, False, True, True]
 
 Now let's see what it does:
 

die spammer skum
diff --git a/blog/entry/DIY_professional_grade_solar_panel_installation/comment_1_36e55b0ee1442202b0de0141bb6af683._comment b/blog/entry/DIY_professional_grade_solar_panel_installation/comment_1_36e55b0ee1442202b0de0141bb6af683._comment
deleted file mode 100644
index 2ab2f157..00000000
--- a/blog/entry/DIY_professional_grade_solar_panel_installation/comment_1_36e55b0ee1442202b0de0141bb6af683._comment
+++ /dev/null
@@ -1,9 +0,0 @@
-[[!comment format=mdwn
- username="kratikawc12@9c0de3354a5df080ca18590d1a95dc5a37ab3174"
- nickname="kratikawc12"
- avatar="http://cdn.libravatar.org/avatar/c6ca6872611820518ecc2de387fadadc"
- subject="solar panel installation Austin"
- date="2020-02-26T07:20:30Z"
- content="""
-I really appreciate this piece of useful information. For more information, you can visit our website: <a href=\"https://austinsolarpanelinstallation.com/\">solar panel installation Austin</a>
-"""]]

Added a comment: solar panel installation Austin
diff --git a/blog/entry/DIY_professional_grade_solar_panel_installation/comment_1_36e55b0ee1442202b0de0141bb6af683._comment b/blog/entry/DIY_professional_grade_solar_panel_installation/comment_1_36e55b0ee1442202b0de0141bb6af683._comment
new file mode 100644
index 00000000..2ab2f157
--- /dev/null
+++ b/blog/entry/DIY_professional_grade_solar_panel_installation/comment_1_36e55b0ee1442202b0de0141bb6af683._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="kratikawc12@9c0de3354a5df080ca18590d1a95dc5a37ab3174"
+ nickname="kratikawc12"
+ avatar="http://cdn.libravatar.org/avatar/c6ca6872611820518ecc2de387fadadc"
+ subject="solar panel installation Austin"
+ date="2020-02-26T07:20:30Z"
+ content="""
+I really appreciate this piece of useful information. For more information, you can visit our website: <a href=\"https://austinsolarpanelinstallation.com/\">solar panel installation Austin</a>
+"""]]

poll vote (I haven't tried it, but want to)
diff --git a/code/kaxxt/feedback.mdwn b/code/kaxxt/feedback.mdwn
index 1195c7ed..20b95675 100644
--- a/code/kaxxt/feedback.mdwn
+++ b/code/kaxxt/feedback.mdwn
@@ -1,4 +1,4 @@
 Whatdayathink? Please vote in the poll, or post your
 experiences/questions to [[/code/Kaxxt/Discussion]].
 
-[[!poll 4 "I tried it, liked it." 0 "I tried it, needs work." 11 "I haven't tried it, but want to" 2 "I don't plan to try it"]]
+[[!poll 4 "I tried it, liked it." 0 "I tried it, needs work." 12 "I haven't tried it, but want to" 2 "I don't plan to try it"]]

poll vote (watched it all, liked it)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index 270458c9..a897950c 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 60 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 61 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

blog update
diff --git a/blog/entry/arduino-copilot_combinators.mdwn b/blog/entry/arduino-copilot_combinators.mdwn
new file mode 100644
index 00000000..27668ed6
--- /dev/null
+++ b/blog/entry/arduino-copilot_combinators.mdwn
@@ -0,0 +1,118 @@
+My framework for programming Arduinos in Haskell has two major
+improvements this week. It's feeling like I'm laying the
+keystone on this project. It's all about the combinators now.
+
+## Sketch combinators
+
+Consider this arduino-copilot program, that does something unless
+a pause button is pushed:
+
+	paused <- input pin3
+	pin4 =: foo @: not paused
+	v <- input a1
+	pin5 =: bar v @: sometimes && not paused
+
+The pause button has to be checked everywhere, and there's a risk
+of forgetting to check it, resulting in unexpected behavior. It would
+be nice to be able to factor that out somehow. Also, notice that it inputs
+from a1 all the time, but won't use that input when pause is pushed.
+It would be nice to be able to avoid that unnecessary work.
+
+The new `whenB` combinator solves all of that:
+
+	paused <- input pin3
+	whenB (not paused) $ do
+		pin4 =: foo
+		v <- input a1
+		pin5 =: bar v @: sometimes
+
+All `whenB` does is takes a `Behavior Bool` and uses it to control
+whether a Sketch runs.  It was not easy to implement, given
+the constraints of Copilot DSL, but it's working. And once I had
+`whenB`, I was able to leverage RebindableSyntax to allow 
+`if then else` expressions to choose between Sketches, as well as between
+Streams.
+
+Now it's easy to start by writing a Sketch that describes a simple behavior,
+like `turnRight` or `goForward`, and glue those together in a straightforward
+way to make a more complex Sketch, like a line-following robot:
+
+	ll <- leftLineSensed
+	rl <- rightLineSensed
+	if ll && rl
+		then stop
+		else if ll
+			then turnLeft
+			else if rl
+				then turnRight
+				else goForward
+
+([Full line following robot example here](https://git.joeyh.name/index.cgi/arduino-copilot.git/plain/examples/robot/demo.hs))
+
+## TypedBehavior combinators
+
+I've complained before that the Copilot DSL limits `Stream` to basic C data
+types, and so progamming with it felt like I was not able to leverage
+the type checker as much as I'd hope to when writing Haskell, to eg
+keep different units of measurement separated.
+
+Well, I found a way around that problem. All it needed was phantom types,
+and some combinators to lift Copilot DSL expressions.
+
+For example, a Sketch that controls a hot water heater certainly
+wants to indicate clearly that temperatures are in C not F, and
+PSI is another important unit. So define some empty types for those units:
+
+	data PSI
+	data Celsius
+
+Using those as the phantom type parameters for TypedBehavior, some
+important values can be defined:
+
+	maxSafePSI :: TypedBehavior PSI Float
+	maxSafePSI = TypedBehavior (constant 45)
+
+	maxWaterTemp :: TypedBehavior Celsius Float
+	maxWaterTemp = TypedBehavior (constant 35)
+
+And functions like this to convert raw ADC readings into our units:
+
+	adcToCelsius :: Behavior Float -> TypedBehavior Celsius Float
+	adcToCelsius v = TypedBehavior $ v * (constant 200 / constant 1024)
+
+And then we can make functions that take these TypedBehaviors and run
+Copilot DSL expressions on the Stream contained within them,
+producing Behaviors suitable for being connected up to pins:
+
+	isSafePSI :: TypedBehavior PSI Float -> Behavior Bool
+	isSafePSI p = liftB2 (<) p maxSafePSI
+	
+	isSafeTemp :: TypedBehavior Celsius Float -> Behavior Bool
+	isSafeTemp t = liftB2 (<) t maxSafePSI
+
+([Full water heater example here](https://git.joeyh.name/index.cgi/arduino-copilot.git/plain/examples/waterheater/demo.hs))
+
+BTW, did you notice the mistake on the last line of code above? No worries;
+the type checker will, so it will blow up at compile time, and not at runtime.
+
+	    • Couldn't match type ‘PSI’ with ‘Celsius’
+	      Expected type: TypedBehavior Celsius Float
+	        Actual type: TypedBehavior PSI Float
+
+The `liftB2` combinator was all I needed to add to support that.
+There's also a `liftB`, and there could be `liftB3` etc. (Could it
+be generalized to a single lift function that supports multiple arities?
+I don't know yet.) It would be good to have more types than just phantom
+types; I particularly miss Maybe; but this does go a long way.
+
+So you can have a good amount of type safety while using Copilot
+to program your Arduino, and you can mix both FRP style and imperative
+style as you like. Enjoy!
+
+----
+
+This work was sponsored by Trenton Cronholm and Jake Vosloo
+on [Patreon](https://patreon.com/joeyh).
+
+[[!tag code/arduino-copilot]]
+[[!tag haskell]]

renam
diff --git a/blog/entry/announcing_arduino-copilot.mdwn b/blog/entry/announcing_arduino-copilot.mdwn
index 34698c19..1ab90ba9 100644
--- a/blog/entry/announcing_arduino-copilot.mdwn
+++ b/blog/entry/announcing_arduino-copilot.mdwn
@@ -142,4 +142,4 @@ Development of arduino-copilot was sponsored by Trenton Cronholm and
 Jake Vosloo [on Patreon](https://patreon.com/joeyh).
 
 [[!tag haskell]]
-[[!tag code/haskell-arduino-copilot]]
+[[!tag code/arduino-copilot]]
diff --git a/blog/entry/arduino-copilot_one_week_along.mdwn b/blog/entry/arduino-copilot_one_week_along.mdwn
index d27c2ab6..d18ae001 100644
--- a/blog/entry/arduino-copilot_one_week_along.mdwn
+++ b/blog/entry/arduino-copilot_one_week_along.mdwn
@@ -72,4 +72,4 @@ Development of arduino-copilot was sponsored by Trenton Cronholm and
 Jake Vosloo [on Patreon](https://patreon.com/joeyh).
 
 [[!tag haskell]]
-[[!tag code/haskell-arduino-copilot]]
+[[!tag code/arduino-copilot]]
diff --git a/code.mdwn b/code.mdwn
index ecab83aa..38766cb0 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -20,7 +20,7 @@ The stuff that's swapped into my local cache at the moment.
 [[easy-peasy-devicetree-squeezy]]
 [[fridge0]]
 [[haskell-filepath-bytestring]]
-[[haskell-arduino-copilot]]
+[[arduino-copilot]]
 
 ## Less active projects
 
diff --git a/code/haskell-arduino-copilot.mdwn b/code/arduino-copilot.mdwn
similarity index 100%
rename from code/haskell-arduino-copilot.mdwn
rename to code/arduino-copilot.mdwn

blog update
diff --git a/blog/entry/arduino-copilot_one_week_along.mdwn b/blog/entry/arduino-copilot_one_week_along.mdwn
new file mode 100644
index 00000000..d27c2ab6
--- /dev/null
+++ b/blog/entry/arduino-copilot_one_week_along.mdwn
@@ -0,0 +1,75 @@
+My framework for programming Arduinos in Haskell in FRP-style is 
+[[a week old|announcing_arduino-copilot]], and it's grown up a lot.
+
+It can do much more than flash a light now. The `=:` operator can now connect
+all kinds of FRP Events to all kinds of outputs. There's some type level
+progamming going on to only allow connections that make sense. For example,
+[[code/arduino-copilot]] knows what pins of an Adruino support DigitalIO and
+which support PWM. There are even nice custom type error messages:
+
+	demo.hs:7:9: error:
+	    • This Pin does not support digital IO
+	    • In a stmt of a 'do' block: a6 =: blinking
+
+I wanted it to be easy to add support to [[code/arduino-copilot]] for using
+Arduino C libraries from Haskell, and that's proven to be the case. I added
+serial support last weekend, which is probably one of the harder libraries. It
+all fell into place once I realized it should not be about individual printfs,
+but about a single FRP behavior that describes all output to the serial port.
+This interface was the result:
+
+	n <- input a1 :: Sketch (Behavior ADC)
+	Serial.device =: [Serial.str "a1:", Serial.show n, Serial.char '\n']
+	Serial.baud 9600
+
+This weekend I've been adding support for the EEPROMex library, and the
+Functional Reactive Programming approach really shines in stuff like this
+example, which gathers data from a sensor, logs it to the serial port, and
+also stores every 3rd value into the EEPROM for later retrival, using the
+whole EEPROM as a rolling buffer.
+
+	v <- input a1 ([10, 20..] :: [ADC])
+	range <- EEPROM.allocRange sizeOfEEPROM :: Sketch (EEPROM.Range ADC)
+	range =: EEPROM.sweepRange 0 v @: frequency 3
+	led =: frequency 3
+	Serial.device =: [ Serial.show v, Serial.char '\n']
+	Serial.baud 9600
+	delay =: MilliSeconds (constant 10000)
+
+There's a fair bit of abstraction in that... Try doing that in 7 lines of C
+code with that level of readability. (It compiles into 120 lines of C.)
+
+Copilot's ability to interpret the program and show what it would do, without
+running it on the Adruino, seems more valuable the more complicated the
+programs become. Here's the interpretation of the program above.
+
+	delay:     digitalWrite_13:      eeprom_range_write1:  output_Serial:       
+	(10000)    (13,false)            --                    (10)                 
+	(10000)    (13,true)             (0,20)                (20)                 
+	(10000)    (13,false)            --                    (30)                 
+	(10000)    (13,false)            --                    (40)                 
+	(10000)    (13,true)             (1,50)                (50)                 
+	(10000)    (13,false)            --                    (60)          
+
+Last night I was writing a program that amoung other things, had an event that
+only happened once every 70 minutes (when the Arduino's `micros` clock
+overflows). I didn't have to wait hours staring at the Arduino to test
+and debug my program, instead I interpreted it with a clock input that
+overflowed on demand.
+
+(Hmm, I've not actually powered my Arduino on in nearly a week despite writing
+new Arduino programs every day.)
+
+So [[code/arduino-copilot]] is feeling like it's something that I'll be using
+soon to write real world Arduino programs. It's certianly is not usable for all
+Arduino programming, but it will support all the kinds of programs I want to
+write, and being able to use Functional Reactive Programming will make me want
+to write them.
+
+----
+
+Development of arduino-copilot was sponsored by Trenton Cronholm and
+Jake Vosloo [on Patreon](https://patreon.com/joeyh).
+
+[[!tag haskell]]
+[[!tag code/haskell-arduino-copilot]]

format + ps
diff --git a/code/moreutils/discussion.mdwn b/code/moreutils/discussion.mdwn
index 7ea8b25d..fc93bb8a 100644
--- a/code/moreutils/discussion.mdwn
+++ b/code/moreutils/discussion.mdwn
@@ -616,4 +616,6 @@ Curiously, running bar.sh directly doesn't have this problem.  I'm not sure what
 
 ## pee
 
-* Please can the manpage warn of the non-preservation of order, on the collected stdout from child processes?  On first inspection with `pee md5sum sha256sum` vs `pee sha256sum md5sum`, and on a fast/idle machine, it looks like stdout are collected and then written. But more complex examples show that stdouts may be interleaved even when there have been no newlines yet, so `pee 'md5sum > foo.md5' 'sha256sum > foo.sha256'` is a much better solution.  Thanks -- m
+* Please can the manpage warn of the non-preservation of order, on the collected stdout from child processes?  
+  On first inspection with `pee md5sum sha256sum` vs `pee sha256sum md5sum`, and on a fast/idle machine, it looks like stdout are collected and then written. But more complex examples show that stdouts may be interleaved even when there have been no newlines yet, so `pee 'md5sum > foo.md5' 'sha256sum > foo.sha256'` is a much better solution.  Thanks -- m  
+  *ps.* no bytes were harmed in our discovery of this behaviour, because we've seen interleaved data too many times before! :-]

request for specific clarification on pee(1) manpage
diff --git a/code/moreutils/discussion.mdwn b/code/moreutils/discussion.mdwn
index 2a9a6571..7ea8b25d 100644
--- a/code/moreutils/discussion.mdwn
+++ b/code/moreutils/discussion.mdwn
@@ -613,3 +613,7 @@ Curiously, running bar.sh directly doesn't have this problem.  I'm not sure what
 
 * [overwrite](https://unix.stackexchange.com/a/11074/176171)
 * [ftrunctate](https://unix.stackexchange.com/a/280277/176171)
+
+## pee
+
+* Please can the manpage warn of the non-preservation of order, on the collected stdout from child processes?  On first inspection with `pee md5sum sha256sum` vs `pee sha256sum md5sum`, and on a fast/idle machine, it looks like stdout are collected and then written. But more complex examples show that stdouts may be interleaved even when there have been no newlines yet, so `pee 'md5sum > foo.md5' 'sha256sum > foo.sha256'` is a much better solution.  Thanks -- m

update for arduino-copilot-1.2.0
diff --git a/blog/entry/announcing_arduino-copilot.mdwn b/blog/entry/announcing_arduino-copilot.mdwn
index 0219923a..34698c19 100644
--- a/blog/entry/announcing_arduino-copilot.mdwn
+++ b/blog/entry/announcing_arduino-copilot.mdwn
@@ -10,7 +10,7 @@ To make your arduino blink its LED, you only need 4 lines of Haskell:
 	import Copilot.Arduino
 	main = arduino $ do
 		led =: blinking
-		delay =: constant 100
+		delay =: constant (MilliSeconds 100)
 
 Running that Haskell program generates an Arduino sketch in an `.ino` file,
 which can be loaded into the Arduino IDE and uploaded to the Arduino the
@@ -59,7 +59,7 @@ time, and then back to fast flashing.
 	main = arduino $ do
 	        buttonpressed <- readfrom pin12
 	        led =: buttonpressed || blinking
-	        delay =: longer_and_longer * 2
+	        delay =: MilliSeconds (longer_and_longer * 2)
 
 This is starting to use features of the Copilot DSL; 
 "`buttonpressed || blinking`" combines two FRP streams together,
@@ -98,7 +98,7 @@ for the simulation:
 Now let's see what it does:
 
 	# runghc demo.hs -i 5
-	delay:         digitalWrite: 
+	delay:         digitalWrite_13: 
 	(2)            (13,false)    
 	(4)            (13,true)     
 	(8)            (13,false)    
diff --git a/blog/entry/announcing_arduino-copilot/comment_2_958ed75df653692e8d54e6c38c2858ab._comment b/blog/entry/announcing_arduino-copilot/comment_2_958ed75df653692e8d54e6c38c2858ab._comment
new file mode 100644
index 00000000..6ed5cde9
--- /dev/null
+++ b/blog/entry/announcing_arduino-copilot/comment_2_958ed75df653692e8d54e6c38c2858ab._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2020-01-28T23:32:53Z"
+ content="""
+There's a more general library that could be factored out of
+arduino-copilot, perhaps, to support other micros that don't use arduino
+sketches being programmed FRP style.
+
+I don't know if bSpokeLight's image processing could be done
+in the Copilot DSL. Maybe.
+"""]]

Added a comment: 8051 too?
diff --git a/blog/entry/announcing_arduino-copilot/comment_1_4370be0bac294783ee40f0d63f6c51b0._comment b/blog/entry/announcing_arduino-copilot/comment_1_4370be0bac294783ee40f0d63f6c51b0._comment
new file mode 100644
index 00000000..12fc10d9
--- /dev/null
+++ b/blog/entry/announcing_arduino-copilot/comment_1_4370be0bac294783ee40f0d63f6c51b0._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="mail@45651620a210591000202a17a15b298f81c5f682"
+ nickname="mail"
+ avatar="http://cdn.libravatar.org/avatar/5823d09208b1e4b63bbfcd189492032c"
+ subject="8051 too?"
+ date="2020-01-26T22:42:44Z"
+ content="""
+It might be fun to use this to reimplement the C code that I wrote for 
+https://github.com/nomeata/bSpokeLight
+
+"""]]

reorg
diff --git a/blog/entry/announcing_arduino-copilot.mdwn b/blog/entry/announcing_arduino-copilot.mdwn
index 90c2822a..0219923a 100644
--- a/blog/entry/announcing_arduino-copilot.mdwn
+++ b/blog/entry/announcing_arduino-copilot.mdwn
@@ -84,6 +84,31 @@ This whole example turns into just 63 lines of C code, which compiles
 to a 1248 byte binary, so there's plenty of room left for larger, more
 complex programs.
 
+## simulating an Arduino
+
+One of Copilot's features is it can interpret code, without needing to
+run it on the target platform. So the Arduino's behavior can be simulated,
+without ever generating C code, right at the console!
+
+But first, one line of code needs to be changed, to provide some button states
+for the simulation:
+
+	        buttonpressed <- readfrom' pin12 [False, False, False, True, True]
+
+Now let's see what it does:
+
+	# runghc demo.hs -i 5
+	delay:         digitalWrite: 
+	(2)            (13,false)    
+	(4)            (13,true)     
+	(8)            (13,false)    
+	(16)           (13,true)     
+	(32)           (13,true)     
+
+Which is exactly what I described it doing! To prove that it always
+behaves correctly, you could use
+[copilot-theorem](https://hackage.haskell.org/package/copilot-theorem).
+
 ## peek at C
 
 Let's look at the C code that is generated by the first example, of
@@ -110,30 +135,6 @@ see few unnecessary double computations. That's all I've found to complain
 about with the generated code. And no matter what you do, Copilot will
 always generate code that runs in constant space, and constant time.
 
-## simulating an Arduino
-
-One of Copilot's features is it can interpret code, without needing to
-run it on the target platform. So the Arduino's behavior can be simulated,
-without ever generating C code, right at the console!
-
-But first, one line of code needs to be changed, to provide some button states
-for the simulation:
-
-	        buttonpressed <- readfrom' pin12 [False, False, False, True, True]
-
-Now let's see what it does:
-
-	# runghc demo.hs -i 5
-	delay:         digitalWrite: 
-	(2)            (13,false)    
-	(4)            (13,true)     
-	(8)            (13,false)    
-	(16)           (13,true)     
-	(32)           (13,true)     
-
-Which is exactly what I described it doing! To prove that it always
-behaves correctly, you could use
-[copilot-theorem](https://hackage.haskell.org/package/copilot-theorem).
 
 ----
 

add peek at C section
diff --git a/blog/entry/announcing_arduino-copilot.mdwn b/blog/entry/announcing_arduino-copilot.mdwn
index 653d68e3..90c2822a 100644
--- a/blog/entry/announcing_arduino-copilot.mdwn
+++ b/blog/entry/announcing_arduino-copilot.mdwn
@@ -84,6 +84,32 @@ This whole example turns into just 63 lines of C code, which compiles
 to a 1248 byte binary, so there's plenty of room left for larger, more
 complex programs.
 
+## peek at C
+
+Let's look at the C code that is generated by the first example, of
+blinking the LED.
+
+This is not the generated code, but a representation of how the C compiler
+sees it, after constant folding, and some very basic optimisation. This
+compiles to the same binary as the generated code.
+
+	void setup() {
+	      pinMode(13, OUTPUT);
+	}
+	void loop(void) {
+	      delay(100);
+	      digitalWrite(13, s0[s0_idx]);
+	      s0_idx = (++s0_idx) % 2;
+	}
+
+If you compare this with hand-written C code to do the same thing,
+this is pretty much optimal!
+
+Looking at the C code generated for the more complex example above, you'll
+see few unnecessary double computations. That's all I've found to complain
+about with the generated code. And no matter what you do, Copilot will
+always generate code that runs in constant space, and constant time.
+
 ## simulating an Arduino
 
 One of Copilot's features is it can interpret code, without needing to

fix link
diff --git a/blog/entry/announcing_arduino-copilot.mdwn b/blog/entry/announcing_arduino-copilot.mdwn
index 79efcfdf..653d68e3 100644
--- a/blog/entry/announcing_arduino-copilot.mdwn
+++ b/blog/entry/announcing_arduino-copilot.mdwn
@@ -115,4 +115,4 @@ Development of arduino-copilot was sponsored by Trenton Cronholm and
 Jake Vosloo [on Patreon](https://patreon.com/joeyh).
 
 [[!tag haskell]]
-[[!tag code/arduino-copilot]]
+[[!tag code/haskell-arduino-copilot]]

blog update
diff --git a/blog/entry/announcing_arduino-copilot.mdwn b/blog/entry/announcing_arduino-copilot.mdwn
new file mode 100644
index 00000000..79efcfdf
--- /dev/null
+++ b/blog/entry/announcing_arduino-copilot.mdwn
@@ -0,0 +1,118 @@
+[arduino-copilot](https://hackage.haskell.org/package/arduino-copilot),
+released today, makes it easy to use Haskell to program an Arduino. It's a FRP
+style system, and uses the [Copilot](https://copilot-language.github.io/) DSL
+to generate embedded C code.
+
+## gotta blink before you can run
+
+To make your arduino blink its LED, you only need 4 lines of Haskell:
+
+	import Copilot.Arduino
+	main = arduino $ do
+		led =: blinking
+		delay =: constant 100
+
+Running that Haskell program generates an Arduino sketch in an `.ino` file,
+which can be loaded into the Arduino IDE and uploaded to the Arduino the
+same as any other sketch. It's also easy to use things like
+`Arduino-Makefile` to build and upload sketches generated by
+arduino-copilot.
+
+## shoulders of giants
+
+Copilot is quite an impressive embedding of C in Haskell. It was developed
+for NASA by Galois and is intended for safety-critical applications. So
+it's neat to be able to repurpose it into hobbyist microcontrollers. (I do
+hope to get more type safety added to Copilot though, currently it seems rather
+easy to confuse eg miles with kilometers when using it.)
+
+I'm not the first person to use Copilot to program an Arduino. 
+Anthony Cowley showed how to do it in
+[Abstractions for the Functional Roboticist](https://vimeo.com/77164337)
+back in 2013. But he had to write a skeleton of C code around
+the C generated by Copilot. Amoung other features, arduino-copilot
+automates generating that C skeleton. So you don't need to remember to
+enable GPIO pin 13 for output in the setup function; arduino-copilot
+sees you're using the LED and does that for you.
+
+[frp-arduino](http://hackage.haskell.org/package/frp-arduino) was a big
+inspiration too, especially how easy it makes it to generate an Arduino sketch
+withough writing any C. The "`=:`" operator in copilot-arduino is copied from it.
+But ftp-arduino contains its own DSL, which seems less capable than Copilot. 
+And when I looked at using frp-arduino for some real world sensing and control,
+it didn't seem to be possible to integrate it with existing Arduino libraries
+written in C. While I've not done that with arduino-copilot yet, I did design it
+so it should be reasonably easy to integrate it with any Arduino library.
+
+## a more interesting example
+
+Let's do something more interesting than flashing a LED.
+We'll assume pin 12 of an Arduino Uno is connected to a push button.
+When the button is pressed, the LED should stay lit. Otherwise, flash
+the LED, starting out flashing it fast, but flashing slower and slower over
+time, and then back to fast flashing.
+
+	{-# LANGUAGE RebindableSyntax #-}
+	import Copilot.Arduino.Uno
+
+	main :: IO ()
+	main = arduino $ do
+	        buttonpressed <- readfrom pin12
+	        led =: buttonpressed || blinking
+	        delay =: longer_and_longer * 2
+
+This is starting to use features of the Copilot DSL; 
+"`buttonpressed || blinking`" combines two FRP streams together,
+and "`longer_and_longer * 2`" does math on a stream.
+What a concise and readable implementation of this Arduino's behavior!
+
+Finishing up the demo program is the implementation of `longer_and_longer`.
+This part is entirely in the Copilot DSL, and actually I lifted it
+from some Copilot example code. It gives a reasonable flavor of what it's
+like to construct streams in Copilot.
+
+	longer_and_longer :: Stream Int16
+	longer_and_longer = counter true $ counter true false `mod` 64 == 0
+	
+	counter :: Stream Bool -> Stream Bool -> Stream Int16
+	counter inc reset = cnt
+	   where
+	        cnt = if reset then 0 else if inc then z + 1 else z
+	        z = [0] ++ cnt
+
+This whole example turns into just 63 lines of C code, which compiles
+to a 1248 byte binary, so there's plenty of room left for larger, more
+complex programs.
+
+## simulating an Arduino
+
+One of Copilot's features is it can interpret code, without needing to
+run it on the target platform. So the Arduino's behavior can be simulated,
+without ever generating C code, right at the console!
+
+But first, one line of code needs to be changed, to provide some button states
+for the simulation:
+
+	        buttonpressed <- readfrom' pin12 [False, False, False, True, True]
+
+Now let's see what it does:
+
+	# runghc demo.hs -i 5
+	delay:         digitalWrite: 
+	(2)            (13,false)    
+	(4)            (13,true)     
+	(8)            (13,false)    
+	(16)           (13,true)     
+	(32)           (13,true)     
+
+Which is exactly what I described it doing! To prove that it always
+behaves correctly, you could use
+[copilot-theorem](https://hackage.haskell.org/package/copilot-theorem).
+
+----
+
+Development of arduino-copilot was sponsored by Trenton Cronholm and
+Jake Vosloo [on Patreon](https://patreon.com/joeyh).
+
+[[!tag haskell]]
+[[!tag code/arduino-copilot]]

new
diff --git a/code.mdwn b/code.mdwn
index 1b9d8389..ecab83aa 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -20,6 +20,7 @@ The stuff that's swapped into my local cache at the moment.
 [[easy-peasy-devicetree-squeezy]]
 [[fridge0]]
 [[haskell-filepath-bytestring]]
+[[haskell-arduino-copilot]]
 
 ## Less active projects
 

new
diff --git a/code/haskell-arduino-copilot.mdwn b/code/haskell-arduino-copilot.mdwn
new file mode 100644
index 00000000..92789ae3
--- /dev/null
+++ b/code/haskell-arduino-copilot.mdwn
@@ -0,0 +1,3 @@
+Arduino programming in haskell using the Copilot stream DSL
+
+<http://hackage.haskell.org/package/arduino-copilot>

Added a comment: Nice read
diff --git a/blog/entry/2020_hindsight/comment_1_3b6e1a0505889857385d4890c5e764b6._comment b/blog/entry/2020_hindsight/comment_1_3b6e1a0505889857385d4890c5e764b6._comment
new file mode 100644
index 00000000..8f81ff8b
--- /dev/null
+++ b/blog/entry/2020_hindsight/comment_1_3b6e1a0505889857385d4890c5e764b6._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="lioh@d60e27fddf08ba15c63b2b18e9521d7bc3453bb1"
+ nickname="lioh"
+ avatar="http://cdn.libravatar.org/avatar/65fa804f4ec5498f7b31a799aff0974d"
+ subject="Nice read"
+ date="2020-01-07T05:54:14Z"
+ content="""
+Thanks for sharing. Very interesting read. I wish you all the best on your way.
+"""]]

calendar update
diff --git a/blog/archives/2020.mdwn b/blog/archives/2020.mdwn
new file mode 100644
index 00000000..5b77de98
--- /dev/null
+++ b/blog/archives/2020.mdwn
@@ -0,0 +1 @@
+[[!calendar type=year year=2020 pages="blog/entry/* and !*/Discussion"]]
diff --git a/blog/archives/2020/01.mdwn b/blog/archives/2020/01.mdwn
new file mode 100644
index 00000000..b3a1b3cc
--- /dev/null
+++ b/blog/archives/2020/01.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=01 year=2020 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(01) and creation_year(2020) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2020/02.mdwn b/blog/archives/2020/02.mdwn
new file mode 100644
index 00000000..94ecd2cc
--- /dev/null
+++ b/blog/archives/2020/02.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=02 year=2020 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(02) and creation_year(2020) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2020/03.mdwn b/blog/archives/2020/03.mdwn
new file mode 100644
index 00000000..7340dfe1
--- /dev/null
+++ b/blog/archives/2020/03.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=03 year=2020 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(03) and creation_year(2020) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2020/04.mdwn b/blog/archives/2020/04.mdwn
new file mode 100644
index 00000000..d24c3726
--- /dev/null
+++ b/blog/archives/2020/04.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=04 year=2020 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(04) and creation_year(2020) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2020/05.mdwn b/blog/archives/2020/05.mdwn
new file mode 100644
index 00000000..bb0c2006
--- /dev/null
+++ b/blog/archives/2020/05.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=05 year=2020 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(05) and creation_year(2020) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2020/06.mdwn b/blog/archives/2020/06.mdwn
new file mode 100644
index 00000000..83d8ca9e
--- /dev/null
+++ b/blog/archives/2020/06.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=06 year=2020 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(06) and creation_year(2020) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2020/07.mdwn b/blog/archives/2020/07.mdwn
new file mode 100644
index 00000000..f173ac48
--- /dev/null
+++ b/blog/archives/2020/07.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=07 year=2020 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(07) and creation_year(2020) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2020/08.mdwn b/blog/archives/2020/08.mdwn
new file mode 100644
index 00000000..0c954fd9
--- /dev/null
+++ b/blog/archives/2020/08.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=08 year=2020 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(08) and creation_year(2020) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2020/09.mdwn b/blog/archives/2020/09.mdwn
new file mode 100644
index 00000000..695319b9
--- /dev/null
+++ b/blog/archives/2020/09.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=09 year=2020 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(09) and creation_year(2020) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2020/10.mdwn b/blog/archives/2020/10.mdwn
new file mode 100644
index 00000000..661cf045
--- /dev/null
+++ b/blog/archives/2020/10.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=10 year=2020 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(10) and creation_year(2020) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2020/11.mdwn b/blog/archives/2020/11.mdwn
new file mode 100644
index 00000000..48fb75f4
--- /dev/null
+++ b/blog/archives/2020/11.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=11 year=2020 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(11) and creation_year(2020) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2020/12.mdwn b/blog/archives/2020/12.mdwn
new file mode 100644
index 00000000..8b3218be
--- /dev/null
+++ b/blog/archives/2020/12.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=12 year=2020 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(12) and creation_year(2020) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]

typo
diff --git a/blog/entry/2020_hindsight.mdwn b/blog/entry/2020_hindsight.mdwn
index 7c95db52..141aa802 100644
--- a/blog/entry/2020_hindsight.mdwn
+++ b/blog/entry/2020_hindsight.mdwn
@@ -36,7 +36,7 @@ After two idyllic years of depleting savings, I did a Kickstarter for
 git-annex and raised not much, but I was now living on very little, so that
 was a [[nice windfall|the_rocket]]. I went full crowdfunding for a couple
 of years. After a while, I started getting contracting work,
-supplimenting the croudfunding, as git-annex found use in science
+supplementing the croudfunding, as git-annex found use in science
 and education. Both have continued ever since, amazingly.
 
 I was free to do whatever I wanted to. A lot of that was

post
diff --git a/blog/entry/2020_hindsight.mdwn b/blog/entry/2020_hindsight.mdwn
index 9bacd239..7c95db52 100644
--- a/blog/entry/2020_hindsight.mdwn
+++ b/blog/entry/2020_hindsight.mdwn
@@ -3,66 +3,71 @@ and suggested I write a followup...)
 
 This has been a big decade for me.
 
-Ten years ago, I'd been in an increasingly stale job for several years
-too long. I was tired of living in the city, and had a yurt as a weekend
-relief valve. I had the feeling a big change was coming.
+[[Ten years ago|naught_but_a_decade]], I'd been in an increasingly stale
+job for several years too long. I was tired of living in the city, and had
+a yurt as a weekend relief valve. I had the feeling a big change was
+coming.
 
 Four months on and I quit my job, despite the ongoing financial crisis
 making prospects poor for other employment, especially work on free software.
 
-I tried to start a business, Branchable, with liw, based on my
-earlier ikiwiki project, but it never really took off. However, I'm proud
+I tried to start a business, Branchable, with liw, based on my earlier
+[[code/ikiwiki]] project, but it never really took off. However, I'm proud
 it's still serving the users it did find, 10 years later.
 
 Then, through luck and connections, I found a patch of land in a blank spot
-in the map with the most absurd rent ever ($5/acre/month). It had a house on
-it, no running water, barely solar power, a phone line, no cell service or
+in the map with the most absurd rent ever ($5/acre/month). It had a 
+[[house|old_house]] on it, no running water, 
+[[barely solar power|solar_day_2]], a phone line, no cell service or
 internet, total privacy.
 
 This proved very inspiring. Once again I was hauling water, chopping wood,
-poking at web pages on the other end of a dialup modem. Just like it were
-2000 again. Now I was also hacking by candle-light until the ancient
-batteries got so depleted I could hear the voltage regulator crackle with
-every surge of CPU activity.
+[poking at web pages on the other end of a dialup modem](https://1-minute-modem.branchable.com/).
+Just like it was 2000 again. Now I was also hacking by lantern-light until
+the [[ancient batteries|solar_year]] got so depleted I could hear the
+voltage regulator crackle with every surge of CPU activity.
 
 I had wanted to learn Haskell, but could never concentrate on it enough. I
-learned me some Haskell and I wrote [[code/git-annex]], my first real world
+learned me some Haskell and wrote [[code/git-annex]], my first real world
 Haskell program, to help me deal with shuttling data back and forth from
 civilization on sneakernet.
 
-After two years of depleting savings, I did a Kickstarter for git-annex and
-raised not much, but I was now living on very little, so that
-was a nice windfall. I went full crowdfunding for a couple of years.
-After a while, I started getting contracting work on git-annex,
-supplimenting the croudfunding. Both have continued ever since, amazingly.
+After two idyllic years of depleting savings, I did a Kickstarter for
+git-annex and raised not much, but I was now living on very little, so that
+was a [[nice windfall|the_rocket]]. I went full crowdfunding for a couple
+of years. After a while, I started getting contracting work,
+supplimenting the croudfunding, as git-annex found use in science
+and education. Both have continued ever since, amazingly.
 
-I was free and working on whatever I wanted to. A lot of that was
+I was free to do whatever I wanted to. A lot of that was
 git-annex, with some Debian, and some smaller projects, too many to list
 here.
 
-Then in 2014, I left the Debian project. I'm still sad, still miss
-everybody, but I also think, if I had not been so free, I would not have
+Then, mid-decade, I left the Debian project. I'm still sad, still miss
+everybody, but I also think, had I not been so free, I would not have
 been able to leave it. It had driven most of my career before this point.
 I was lucky to be able to leave Debian. 💧
 
-Adding to the stress, my patch of countryside was being sold out from under me.
-I considered moving to some city, but the income that's freeing here would be
-barely getting by there. I bought the place, using git-annex income,
-plus a crucial loan from a wonderful friend.
+Adding to the stress of that, my patch of countryside was being sold out
+from under me. I considered moving to some city, but the income that's
+freeing here would be barely getting by there. Instead, I bought the place,
+using git-annex income, plus a crucial loan from a wonderful friend.
 
 That changed how I dealt with being offgrid. Before it was an interesting
 constraint, something to adapt to, an added texture to life. Now it's all of
-those and also a source of inspiration and learning. How to install solar
-panels on a roof. How to wire things to code. Circuit design. Plumbing.
-Ditch digging. Functional reactive programming for automation.
-With my [[offgrid fridge|code/fride0]] project, offgrid things 
-are getting interdisciplinary in ways my work has not been before.
+those and also a source of inspiration and learning. How to 
+[[install solar panels on a roof|DIY_professional_grade_solar_panel_installation]].
+How to wire things to code. [[Circuit design|AIMS_inverter_control_via_GPIO_ports]].
+[[Plumbing|hacking_water]]. [[Ditch digging|hacking_water]].
+With my [[offgrid fridge|code/fridge0]] project, things are feeling
+interdisciplinary in ways my work has not been before.
+
+From here at its end, this decade feels both inevitable and highly unlikely.
+Now I feel.. comfortable. Settled. Surely older. More unsure of myself
+than ever really, nearly everything is more complicated than I used to think
+it was. Maybe a little stuck? But not really.
 
-From here, this decade feels both inevitable and highly unlikely.
-Now I feel.. comfortable. Settled. Maybe a little stuck? But not really.
 I'm planting fruit trees, something says I will be here to enjoy them.
-But times are getting interesting. Anything could be around the corner.
+But times are getting beyond interesting. Anything could be around the corner.
 
 [[!tag lay]]
-
-[[!tag unfinished]]

blog update
diff --git a/blog/entry/2020_hindsight.mdwn b/blog/entry/2020_hindsight.mdwn
new file mode 100644
index 00000000..9bacd239
--- /dev/null
+++ b/blog/entry/2020_hindsight.mdwn
@@ -0,0 +1,68 @@
+(Someone stumbled upon my [[2010 decade retrospective post|naught_but_a_decade]]
+and suggested I write a followup...)
+
+This has been a big decade for me.
+
+Ten years ago, I'd been in an increasingly stale job for several years
+too long. I was tired of living in the city, and had a yurt as a weekend
+relief valve. I had the feeling a big change was coming.
+
+Four months on and I quit my job, despite the ongoing financial crisis
+making prospects poor for other employment, especially work on free software.
+
+I tried to start a business, Branchable, with liw, based on my
+earlier ikiwiki project, but it never really took off. However, I'm proud
+it's still serving the users it did find, 10 years later.
+
+Then, through luck and connections, I found a patch of land in a blank spot
+in the map with the most absurd rent ever ($5/acre/month). It had a house on
+it, no running water, barely solar power, a phone line, no cell service or
+internet, total privacy.
+
+This proved very inspiring. Once again I was hauling water, chopping wood,
+poking at web pages on the other end of a dialup modem. Just like it were
+2000 again. Now I was also hacking by candle-light until the ancient
+batteries got so depleted I could hear the voltage regulator crackle with
+every surge of CPU activity.
+
+I had wanted to learn Haskell, but could never concentrate on it enough. I
+learned me some Haskell and I wrote [[code/git-annex]], my first real world
+Haskell program, to help me deal with shuttling data back and forth from
+civilization on sneakernet.
+
+After two years of depleting savings, I did a Kickstarter for git-annex and
+raised not much, but I was now living on very little, so that
+was a nice windfall. I went full crowdfunding for a couple of years.
+After a while, I started getting contracting work on git-annex,
+supplimenting the croudfunding. Both have continued ever since, amazingly.
+
+I was free and working on whatever I wanted to. A lot of that was
+git-annex, with some Debian, and some smaller projects, too many to list
+here.
+
+Then in 2014, I left the Debian project. I'm still sad, still miss
+everybody, but I also think, if I had not been so free, I would not have
+been able to leave it. It had driven most of my career before this point.
+I was lucky to be able to leave Debian. 💧
+
+Adding to the stress, my patch of countryside was being sold out from under me.
+I considered moving to some city, but the income that's freeing here would be
+barely getting by there. I bought the place, using git-annex income,
+plus a crucial loan from a wonderful friend.
+
+That changed how I dealt with being offgrid. Before it was an interesting
+constraint, something to adapt to, an added texture to life. Now it's all of
+those and also a source of inspiration and learning. How to install solar
+panels on a roof. How to wire things to code. Circuit design. Plumbing.
+Ditch digging. Functional reactive programming for automation.
+With my [[offgrid fridge|code/fride0]] project, offgrid things 
+are getting interdisciplinary in ways my work has not been before.
+
+From here, this decade feels both inevitable and highly unlikely.
+Now I feel.. comfortable. Settled. Maybe a little stuck? But not really.
+I'm planting fruit trees, something says I will be here to enjoy them.
+But times are getting interesting. Anything could be around the corner.
+
+[[!tag lay]]
+
+[[!tag unfinished]]

comment
diff --git a/blog/archives/2010/01/discussion.mdwn b/blog/archives/2010/01/discussion.mdwn
new file mode 100644
index 00000000..60b6956e
--- /dev/null
+++ b/blog/archives/2010/01/discussion.mdwn
@@ -0,0 +1 @@
+As the sun sets on another decade, I hope you post another writing reflecting on the past 10 years, the changes, and some milestones. I hope to join you in my own western island of Offgridistan in the not-so-distant future.

comment
diff --git a/blog/entry/announcing_the_filepath-bytestring_haskell_library/comment_1_b8887a5557ff195ddacb67f3ea8e3c80._comment b/blog/entry/announcing_the_filepath-bytestring_haskell_library/comment_1_b8887a5557ff195ddacb67f3ea8e3c80._comment
new file mode 100644
index 00000000..e2a222a4
--- /dev/null
+++ b/blog/entry/announcing_the_filepath-bytestring_haskell_library/comment_1_b8887a5557ff195ddacb67f3ea8e3c80._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2019-12-11T19:02:06Z"
+ content="""
+Using this library in git-annex, I saw a real-world speedup of 30%
+in `git annex find`. That command has to read a list of files from 
+`git ls-files`, and read all their symlinks, and check if the symlinks are
+broken or not. So there's a fair amount of IO, but FilePath overhead was
+still significant and worth eliminating.
+"""]]

blog update
diff --git a/blog/entry/announcing_the_filepath-bytestring_haskell_library.mdwn b/blog/entry/announcing_the_filepath-bytestring_haskell_library.mdwn
new file mode 100644
index 00000000..ff684617
--- /dev/null
+++ b/blog/entry/announcing_the_filepath-bytestring_haskell_library.mdwn
@@ -0,0 +1,22 @@
+[filepath-bytestring](https://hackage.haskell.org/package/filepath-bytestring)
+is a drop-in replacement for the standard haskell
+[filepath](https://hackage.haskell.org/package/filepath)
+library, that operates on RawFilePath rather than FilePath.
+
+The benefit, of course, is speed. `"foo" </> "bar"` is around 25% faster
+with the new library. `dropTrailingPathSeparator`
+is 120% faster. But the real speed benefits probably come when a program
+is able to input filepaths as ByteStrings, manipulate them, and operate
+on the files, all without using String.
+
+It's extensively tested, not only does it run all the same doctests
+that the filepath library does, but each function is quickchecked to
+behave the same as the equivilant function from filepath.
+
+While I implemented almost everything, I did leave
+off some functions that operate on PATH, which seem unlikely to be useful,
+and the complicated `normalise` and stuff that uses it.
+
+This work was sponsored by Jake Vosloo [on Patron](https://patreon.com/joeyh/).
+
+[[!tag code/haskell-filepath-bytestring haskell]]

add
diff --git a/code.mdwn b/code.mdwn
index 29cc1a79..1b9d8389 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -19,6 +19,7 @@ The stuff that's swapped into my local cache at the moment.
 [[reactive-banana-automation]]
 [[easy-peasy-devicetree-squeezy]]
 [[fridge0]]
+[[haskell-filepath-bytestring]]
 
 ## Less active projects
 
diff --git a/code/haskell-filepath-bytestring.mdwn b/code/haskell-filepath-bytestring.mdwn
new file mode 100644
index 00000000..d93b3dbd
--- /dev/null
+++ b/code/haskell-filepath-bytestring.mdwn
@@ -0,0 +1,3 @@
+haskell library like `filepath` but for RawFilePaths.
+
+<http://hackage.haskell.org/package/filepath-bytestring>

Added a comment: other data beside emails?
diff --git a/blog/entry/counterpoint_on_Yahoo_Groups_archiving/comment_1_9ce30dd3e43877e654c538dde1fd14db._comment b/blog/entry/counterpoint_on_Yahoo_Groups_archiving/comment_1_9ce30dd3e43877e654c538dde1fd14db._comment
new file mode 100644
index 00000000..2cbfdfe1
--- /dev/null
+++ b/blog/entry/counterpoint_on_Yahoo_Groups_archiving/comment_1_9ce30dd3e43877e654c538dde1fd14db._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="valhalla-l@e2780e0d58d6ecca363abfbfa3e831cb7ff27b6b"
+ nickname="valhalla-l"
+ avatar="http://cdn.libravatar.org/avatar/a07f8021309ce9a02c37940c99a8ae12"
+ subject="other data beside emails?"
+ date="2019-12-10T16:40:55Z"
+ content="""
+As far as I remember, yahoo groups didn't just offer a mailing list, but also storage for shared files (and I've seen the feature used extensively); those files haven't been pushed to anybody's mailbox and so are at a higher risk of disappearing (if the submitter doesn't have them properly¹ backed up themselves and is still available to re-upload them elsewhere, of course).
+
+¹ once locally for ease of retrieval, once 30km away, 30 meters up from ground level, once 30 km away from both locations, 30 meters underground.
+"""]]

Added a comment
diff --git a/blog/entry/how_I_maybe_didnt_burn_out/comment_5_e78e4e720e49b844b5911b40d4bd77cf._comment b/blog/entry/how_I_maybe_didnt_burn_out/comment_5_e78e4e720e49b844b5911b40d4bd77cf._comment
new file mode 100644
index 00000000..58c627e1
--- /dev/null
+++ b/blog/entry/how_I_maybe_didnt_burn_out/comment_5_e78e4e720e49b844b5911b40d4bd77cf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="CandyAngel"
+ avatar="http://cdn.libravatar.org/avatar/15c0aade8bec5bf004f939dd73cf9ed8"
+ subject="comment 5"
+ date="2019-12-10T13:01:25Z"
+ content="""
+I would have been happy to help, you only had to ask.
+"""]]

typo
diff --git a/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn b/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn
index eec9baa4..7cf6870c 100644
--- a/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn
+++ b/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn
@@ -4,7 +4,7 @@ they're deleting these mailing list archives, and
 [blocking attempts to save them](https://modsandmembersblog.wordpress.com/2019/12/08/verizon-yahoo-bad-form/)
 and so huge amount of things will be lost from the historical record.
 
-That's a common story these data, but it's not entirely accurate in this
+That's a common story these days, but it's not entirely accurate in this
 case. These are mailing lists, so they're not necessarily only archived by
 Yahoo. Anyone who subscribed to a mailing list may have archived it. I've
 been on a couple of those mailing lists, and the emails I kept from them are

typo
diff --git a/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn b/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn
index 8e9a4238..eec9baa4 100644
--- a/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn
+++ b/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn
@@ -7,7 +7,7 @@ and so huge amount of things will be lost from the historical record.
 That's a common story these data, but it's not entirely accurate in this
 case. These are mailing lists, so they're not necessarily only archived by
 Yahoo. Anyone who subscribed to a mailing list may have archived it. I've
-been on a couple of those mailing lists, and the email I kept from them are
+been on a couple of those mailing lists, and the emails I kept from them are
 already archived rather well (10+ copies). I probably didn't keep every
 email, and I probably won't be exhuming those emails to add them to some
 large archive.org collection of Yahoo Groups. But multiply all the people

link
diff --git a/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn b/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn
index 0d8a92e7..8e9a4238 100644
--- a/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn
+++ b/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn
@@ -20,3 +20,5 @@ enough to satisfy a historian.
 
 Probably even after Gmail and the other cloud mail services shut down and
 delete all *their* archives.
+
+Previously: [[I_am_ArchiveTeam]] (but not speaking for them above)

blog update
diff --git a/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn b/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn
new file mode 100644
index 00000000..0d8a92e7
--- /dev/null
+++ b/blog/entry/counterpoint_on_Yahoo_Groups_archiving.mdwn
@@ -0,0 +1,22 @@
+Yahoo Groups being shut down and the data deleted is a big enough story
+that it's being talked about on the radio. The typical presentation is that
+they're deleting these mailing list archives, and
+[blocking attempts to save them](https://modsandmembersblog.wordpress.com/2019/12/08/verizon-yahoo-bad-form/)
+and so huge amount of things will be lost from the historical record.
+
+That's a common story these data, but it's not entirely accurate in this
+case. These are mailing lists, so they're not necessarily only archived by
+Yahoo. Anyone who subscribed to a mailing list may have archived it. I've
+been on a couple of those mailing lists, and the email I kept from them are
+already archived rather well (10+ copies). I probably didn't keep every
+email, and I probably won't be exhuming those emails to add them to some
+large archive.org collection of Yahoo Groups. But multiply all the people
+who subscribed to these lists by all the traffic to them, by the
+probability that people keep copies of mailing list mails, and there's a
+huge, well-distributed archive of Yahoo Groups out there.
+
+That ensures some of it will survive in the historical record, probably
+enough to satisfy a historian.
+
+Probably even after Gmail and the other cloud mail services shut down and
+delete all *their* archives.

post
diff --git a/blog/entry/left_handed_scissors.mdwn b/blog/entry/left_handed_scissors.mdwn
new file mode 100644
index 00000000..4dc864f9
--- /dev/null
+++ b/blog/entry/left_handed_scissors.mdwn
@@ -0,0 +1,8 @@
+They return my hand's grasp, smotheringly close. Was this how it was meant
+to feel, in a classroom cutting multi-colored construction paper? Not a pain
+to be gotten through, but comfort, closeness, togetherness. Their design
+now feels aggressively overdone, broad curve just so around the thumb,
+as if they might tighten and snap it off. Only too large index finger's
+knuckle, chafing, provides some relief, some reminder that I shouldn't run.
+
+(Thanks, liw.)

Added a comment: Thanks Joey for all your labor over the years
diff --git a/blog/entry/how_I_maybe_didnt_burn_out/comment_4_012b4cefa227327121b8ef9e93bf8088._comment b/blog/entry/how_I_maybe_didnt_burn_out/comment_4_012b4cefa227327121b8ef9e93bf8088._comment
new file mode 100644
index 00000000..55b33f0c
--- /dev/null
+++ b/blog/entry/how_I_maybe_didnt_burn_out/comment_4_012b4cefa227327121b8ef9e93bf8088._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="eric@32f82325cb666b88570a0d152d9605f5f5923e78"
+ nickname="eric"
+ avatar="http://cdn.libravatar.org/avatar/fbecd2cf5679e59a46df57e550fa6e51"
+ subject="Thanks Joey for all your labor over the years"
+ date="2019-11-25T10:21:07Z"
+ content="""
+I'm an Ikiwiki user since way back and am finally about to deploy git-annex across my devices after too many data losses with syncthing.
+
+I have always been inspired by your work and ethics. It's tough to find good role models so thank you.
+"""]]

poll vote (watched it all, liked it)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index 1717fcdf..270458c9 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 59 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 60 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

Added a comment: Off-topic
diff --git a/blog/entry/how_I_maybe_didnt_burn_out/comment_3_8b0295c9e6bdb28eb2e01dca7a513081._comment b/blog/entry/how_I_maybe_didnt_burn_out/comment_3_8b0295c9e6bdb28eb2e01dca7a513081._comment
new file mode 100644
index 00000000..afeea16f
--- /dev/null
+++ b/blog/entry/how_I_maybe_didnt_burn_out/comment_3_8b0295c9e6bdb28eb2e01dca7a513081._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="meribold"
+ avatar="http://cdn.libravatar.org/avatar/8cfdfc37c8459a7320aa6bb9f2689112"
+ subject="Off-topic"
+ date="2019-11-03T06:18:57Z"
+ content="""
+I just want to say that git-annex is awesome and makes my life better.
+"""]]

Added a comment: sorry, and thoughts
diff --git a/blog/entry/how_I_maybe_didnt_burn_out/comment_2_6446db82e8cff3737c41e0d4b6b30e29._comment b/blog/entry/how_I_maybe_didnt_burn_out/comment_2_6446db82e8cff3737c41e0d4b6b30e29._comment
new file mode 100644
index 00000000..831ab947
--- /dev/null
+++ b/blog/entry/how_I_maybe_didnt_burn_out/comment_2_6446db82e8cff3737c41e0d4b6b30e29._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="Ilya_Shlyakhter"
+ avatar="http://cdn.libravatar.org/avatar/34c90de0aa8b47144f32671827bd97d1"
+ subject="sorry, and thoughts"
+ date="2019-10-30T19:05:14Z"
+ content="""
+Sorry Joey it went down like this.  People focus on their own use case and don't always consider the larger picture.  Which is how one ends up pushing [half-baked fixes](https://git-annex.branchable.com/todo/separate_annex.largefiles.git-add_and_annex.largefiles.git-annex-add_settings/) that break [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself).  Your final design is certainly better.
+
+In retrospect I see how my adding to an already one-sided discussion felt like 'piling on'. Sorry about that.
+
+I think people's reaction stemmed not from \"a decision about git-annex\", but from a decision about git, which people still see as a distinct tool, even when used on repos with annexes.  Pure-git workflows on such repos were affected.  People are \"fearful of change\" to git, \"invested in it, and so defensive of how they want it to work\" -- but this may not yet be true for git-annex.
+"""]]

removed
diff --git a/blog/entry/how_I_maybe_didnt_burn_out/comment_2_cbd45ad8ea6c025924b1757e754893e7._comment b/blog/entry/how_I_maybe_didnt_burn_out/comment_2_cbd45ad8ea6c025924b1757e754893e7._comment
deleted file mode 100644
index 8c09dc2a..00000000
--- a/blog/entry/how_I_maybe_didnt_burn_out/comment_2_cbd45ad8ea6c025924b1757e754893e7._comment
+++ /dev/null
@@ -1,15 +0,0 @@
-[[!comment format=mdwn
- username="Ilya_Shlyakhter"
- avatar="http://cdn.libravatar.org/avatar/34c90de0aa8b47144f32671827bd97d1"
- subject="sorry"
- date="2019-10-28T21:25:44Z"
- content="""
-Sorry Joey it went down like this.  People focus on their own use case and don't always consider the larger picture.  Which is how one ends up pushing [half-baked fixes](https://git-annex.branchable.com/todo/separate_annex.largefiles.git-add_and_annex.largefiles.git-annex-add_settings/) that break [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself).  Your final design is
-certainly better.
-
-In retrospect I see how my adding to an already one-sided discussion felt like 'piling on'.   Sorry about that.
-
-I think people's reaction is in part testament to git-annex's success, and to how [basic](https://www.goodreads.com/quotes/322979-there-was-no-way-his-imagination-could-feel-the-impact) to people's work it has become.
-
-
-"""]]

Added a comment: sorry
diff --git a/blog/entry/how_I_maybe_didnt_burn_out/comment_2_cbd45ad8ea6c025924b1757e754893e7._comment b/blog/entry/how_I_maybe_didnt_burn_out/comment_2_cbd45ad8ea6c025924b1757e754893e7._comment
new file mode 100644
index 00000000..8c09dc2a
--- /dev/null
+++ b/blog/entry/how_I_maybe_didnt_burn_out/comment_2_cbd45ad8ea6c025924b1757e754893e7._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="Ilya_Shlyakhter"
+ avatar="http://cdn.libravatar.org/avatar/34c90de0aa8b47144f32671827bd97d1"
+ subject="sorry"
+ date="2019-10-28T21:25:44Z"
+ content="""
+Sorry Joey it went down like this.  People focus on their own use case and don't always consider the larger picture.  Which is how one ends up pushing [half-baked fixes](https://git-annex.branchable.com/todo/separate_annex.largefiles.git-add_and_annex.largefiles.git-annex-add_settings/) that break [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself).  Your final design is
+certainly better.
+
+In retrospect I see how my adding to an already one-sided discussion felt like 'piling on'.   Sorry about that.
+
+I think people's reaction is in part testament to git-annex's success, and to how [basic](https://www.goodreads.com/quotes/322979-there-was-no-way-his-imagination-could-feel-the-impact) to people's work it has become.
+
+
+"""]]

Added a comment: sorry
diff --git a/blog/entry/how_I_maybe_didnt_burn_out/comment_1_02d38e627d54aa0b8b83bd83ece3415b._comment b/blog/entry/how_I_maybe_didnt_burn_out/comment_1_02d38e627d54aa0b8b83bd83ece3415b._comment
new file mode 100644
index 00000000..ee336fb4
--- /dev/null
+++ b/blog/entry/how_I_maybe_didnt_burn_out/comment_1_02d38e627d54aa0b8b83bd83ece3415b._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="anarcat"
+ avatar="http://cdn.libravatar.org/avatar/4ad594c1e13211c1ad9edb81ce5110b7"
+ subject="sorry"
+ date="2019-10-28T17:13:23Z"
+ content="""
+I'm sorry you had to go through with this joey... It's really too bad! Working on those projects should be fun, and while there can be friction sometimes, it shouldn't completely take the fun away. :) I do encourage you to do things the way they are going to make you feel better, and disengaging from the conversation does seem like a good stopgap measure.
+
+I think one of the problems is, as you identified, that everything is in the same bag: bug reports, documentation, todo lists, design discussion *and* the user forum are all in the same wiki. And ikiwik is great, but it's not the best forum tool out there. It lacks things like community moderation, for example...
+
+Maybe it's time to revisit the [forum system discussion](https://git-annex.branchable.com/todo/enable_a_discussion_forum_or_support_system/) again? I don't mean to bring you back to the site, but I suspect significant parts of the community would be quite happy to engage with user support, moderation and administration of a forum. It would take away a *lot* of traffic from the website and create a community for users that would feel like home.  You could, of course, participate there, but it would keep the more technical discussions (bug reports and official feature requests) separate from the larger group of users.
+
+Discourse does offer free hosting for free software projects, by the way. It might be something that could work for you. Or you could just squat an existing instance, although I'm not sure that there's an existing one that could match... Maybe https://pixls.us? There has been quite a few git-annex conversations over there and while I suspect I'm a minority in this, I do manage my photos with git-annex, so it's kind of on topic. :)
+
+let me know if i can help any further! -- [[anarcat]]
+"""]]

blog update
diff --git a/blog/entry/how_I_maybe_didnt_burn_out.mdwn b/blog/entry/how_I_maybe_didnt_burn_out.mdwn
new file mode 100644
index 00000000..7767a706
--- /dev/null
+++ b/blog/entry/how_I_maybe_didnt_burn_out.mdwn
@@ -0,0 +1,62 @@
+Last week I found myself in the uncomfortable position of many users
+strongly disagreeing with a decision I had made about git-annex. It felt
+much like a pile-on of them vs me, strong language was being deployed, and it
+was starting to get mentioned in multiple places on the website, in ways I
+felt would lead to fear, uncertainty, and doubt when other users saw it.
+
+It did not help that I had dental implant surgery recently, and was still
+more in recovery than I knew when I finally tackled looking at this long
+thread. So it hit hard.
+
+I've been involved in software projects that have a sometimes adversarial
+relationship with their users. At times, Debian has been one. I don't know
+if it is today, but I remember being on #debian and #debian-devel, or
+debian-user@lists and debian-devel@lists, and seeing two almost 
+entirely diverged communities who were interacting only begrudgingly and
+with friction.
+
+I don't want that in any of my projects now. My perspective on the
+history of git-annex is that most of the best developments have come after
+I made a not great decision or a mistake and got user feedback, and we
+talked it over and found a way to improve things, leading to a better
+result than would have been possible without the original mistake, much
+how a broken bone heals stronger. So this felt wrong, wrong, wrong.
+
+Part of the problem with this discussion was that, though I'd tried to
+explain the constraints that led to the design decision -- which I'd made
+well over three years ago -- not everyone was able to follow that or engage
+with it constructively. Largely, I think because git-annex has a lot more
+users now, with a wider set of viewpoints.
+(Which is generally why Debian has to split off user discussions of course.)
+The users are more fearful of change than earlier adopters tended to be,
+and have more to lose if git-annex stops meeting their use case. They're
+invested in it, and so defensive of how they want it to work.
+
+It also doesn't help that, surgery aside, I lack time to keep up with every
+discussion about git-annex now, if I'm going to also develop it. Just
+looking at the website tends to eat an entire day with maybe a couple bug
+fixes and some support answers being the only productive result. So, I have
+stepped back from following the git-annex website at all, for now. (I'll
+eventually start looking at parts of it again I'm sure.)
+
+I did find enough value in the thread that I was able to develop a fix that
+should meet everyone's needs, as I now understand them (released in version
+7.20191024). I actually come away with entirely new use cases; I did not
+realize that some users would perhaps use git-annex for a single large file
+in a repository otherwise kept entirely in git. Or quite how many users mix
+storing files in git and git-annex, which I have always seen as somewhat of
+an exception aside from the odd dotfile.
+
+So the open questions are: How do I keep up with discussion and support
+traffic now; can I find someone to provide lower-level support and filtering
+or something? (Good news is, some funding could probably be arranged.)
+How do I prevent the git-annex community fracturing along users/developer
+lines as it grows, given that I don't want to work within such a fractured
+community?
+
+I've been working on git-annex for 9 years this week. Have I avoided
+burning out? Probably, but maybe too early to tell. I think that being able
+to ask these questions is a good thing. I'd appreciate hearing from anyone
+who has grappled with these issues in their own software communities.
+
+[[!meta title="how I maybe didn't burn out"]]

link to new location for kickstarter video
diff --git a/blog/entry/kickstarter_for_git-annex_assistant.mdwn b/blog/entry/kickstarter_for_git-annex_assistant.mdwn
index e0b67cf9..fb496e18 100644
--- a/blog/entry/kickstarter_for_git-annex_assistant.mdwn
+++ b/blog/entry/kickstarter_for_git-annex_assistant.mdwn
@@ -39,4 +39,8 @@ video.
 Anyway, please consider [backing me](http://www.kickstarter.com/projects/joeyh/git-annex-assistant-like-dropbox-but-with-your-own) if you can, and more importantly,
 do anything you can to help spread the word. Thanks!
 
+> 2019 update: Kickstarter is no longer hosting the video,
+> so I've pulled it out of git-annex storage and put it
+> [here](https://downloads.kitenet.net/videos/kickstarter.avi).
+
 [[!meta title="kickstarter for git-annex assistant"]]

typo
diff --git a/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn b/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
index fe65d2c7..e897e1f3 100644
--- a/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
+++ b/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
@@ -7,7 +7,7 @@ With a 5 watt LED bulb (sold separately), the lamp will total a mere 7.2
 watts while on, making it extremely energy efficient. While off, the lamp
 consumes a mere 19 kilowatt-hours per year.
 
-[[!img blog/pics/lamp/wastful.jpg size=400x alt="camp multimeter reading 0.02 amps AC, connected to a small circuit board with a yellow capacitor, a coil, and a heat sinked IC visible"]]
+[[!img blog/pics/lamp/wastful.jpg size=400x alt="clamp multimeter reading 0.02 amps AC, connected to a small circuit board with a yellow capacitor, a coil, and a heat sinked IC visible"]]
 [[!img blog/pics/lamp/rear.jpg size=400x alt="lamp from rear; a small round rocker switch has been added to the top of its half-globe shade"]]
 
 Though the lamp shade at first appears perhaps flimsy, while you are

update
diff --git a/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn b/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
index ad0550fb..fe65d2c7 100644
--- a/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
+++ b/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
@@ -17,8 +17,9 @@ last for generations, should the planet continue to support human life
 for that long.
 
 As an additional bonus, the small plastic project box that comes free in
-this lamp will delight any electrical enthusiast. The 2 cubic foot of
-syrofoam packaging is less delightful.
+this lamp will delight any electrical enthusiast. As will the approximately
+1 hour conversion process to delete the touch switch phantom load. 
+The 2 cubic foot of syrofoam packaging is less delightful.
 
 Two allen screws attach the pole to the base; one was missing in my lamp.
 Also, while the base is very heavily weighted, the lamp still rocks a bit

syro
diff --git a/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn b/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
index 450b113c..ad0550fb 100644
--- a/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
+++ b/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
@@ -17,7 +17,8 @@ last for generations, should the planet continue to support human life
 for that long.
 
 As an additional bonus, the small plastic project box that comes free in
-this lamp will delight any electrical enthusiast.
+this lamp will delight any electrical enthusiast. The 2 cubic foot of
+syrofoam packaging is less delightful.
 
 Two allen screws attach the pole to the base; one was missing in my lamp.
 Also, while the base is very heavily weighted, the lamp still rocks a bit

wording
diff --git a/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn b/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
index 0bf7769c..450b113c 100644
--- a/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
+++ b/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
@@ -16,7 +16,7 @@ metal, though not brass all the way through. Indeed, this lamp should
 last for generations, should the planet continue to support human life
 for that long.
 
-As an additional bonus, the small black project box that comes free in
+As an additional bonus, the small plastic project box that comes free in
 this lamp will delight any electrical enthusiast.
 
 Two allen screws attach the pole to the base; one was missing in my lamp.

final
diff --git a/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn b/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
index 99b4d7cc..0bf7769c 100644
--- a/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
+++ b/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
@@ -7,15 +7,14 @@ With a 5 watt LED bulb (sold separately), the lamp will total a mere 7.2
 watts while on, making it extremely energy efficient. While off, the lamp
 consumes a mere 19 kilowatt-hours per year.
 
-[[!img size=1024x blog/pics/lamp/wastful.jpg alt="camp multimeter reading 0.02 amps AC, connected to a small circuit board with a yellow capacitor, a coil, and a heat sinked IC visible"]]
+[[!img blog/pics/lamp/wastful.jpg size=400x alt="camp multimeter reading 0.02 amps AC, connected to a small circuit board with a yellow capacitor, a coil, and a heat sinked IC visible"]]
+[[!img blog/pics/lamp/rear.jpg size=400x alt="lamp from rear; a small round rocker switch has been added to the top of its half-globe shade"]]
 
-While the lamp shade at first appears perhaps flimsy, while you are drilling
-a hole in it to add a physical switch, you will discover it's a reasonably
-soft metal, though not brass all the way through. Indeed, this lamp should
-last for generations, should the planet continue to support human life for
-that long.
-
-[[!img size=1024x blog/pics/lamp/rear.jpg alt="lamp from rear; a small round rocker switch has been added to the top of its half-globe shade"]]
+Though the lamp shade at first appears perhaps flimsy, while you are
+drilling a hole in it to add a physical switch, you will discover
+metal, though not brass all the way through. Indeed, this lamp should
+last for generations, should the planet continue to support human life
+for that long.
 
 As an additional bonus, the small black project box that comes free in
 this lamp will delight any electrical enthusiast.
@@ -25,5 +24,5 @@ Also, while the base is very heavily weighted, the lamp still rocks a bit
 when using the aftermarket switch. So I am forced to give it a mere 4 out
 of 5 stars.
 
-[[!img size=1024x blog/pics/lamp/front.jpg alt="front view of lit lamp beside a bookcase"]]
+[[!img blog/pics/lamp/front.jpg size=640x alt="front view of lit lamp beside a bookcase"]]
 

blog update
diff --git a/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn b/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
new file mode 100644
index 00000000..99b4d7cc
--- /dev/null
+++ b/blog/entry/Project_62_Valencia_Floor_Lamp_review.mdwn
@@ -0,0 +1,29 @@
+From Target, this brass finish floor lamp evokes 60's modernism,
+updated for the mid-Anthropocene with a touch plate switch.
+
+The integrated microcontroller consumes a mere 2.2 watts while the lamp is
+turned off, in order to allow you to turn the lamp on with a stylish flick.
+With a 5 watt LED bulb (sold separately), the lamp will total a mere 7.2
+watts while on, making it extremely energy efficient. While off, the lamp
+consumes a mere 19 kilowatt-hours per year.
+
+[[!img size=1024x blog/pics/lamp/wastful.jpg alt="camp multimeter reading 0.02 amps AC, connected to a small circuit board with a yellow capacitor, a coil, and a heat sinked IC visible"]]
+
+While the lamp shade at first appears perhaps flimsy, while you are drilling
+a hole in it to add a physical switch, you will discover it's a reasonably
+soft metal, though not brass all the way through. Indeed, this lamp should
+last for generations, should the planet continue to support human life for
+that long.
+
+[[!img size=1024x blog/pics/lamp/rear.jpg alt="lamp from rear; a small round rocker switch has been added to the top of its half-globe shade"]]
+
+As an additional bonus, the small black project box that comes free in
+this lamp will delight any electrical enthusiast.
+
+Two allen screws attach the pole to the base; one was missing in my lamp.
+Also, while the base is very heavily weighted, the lamp still rocks a bit
+when using the aftermarket switch. So I am forced to give it a mere 4 out
+of 5 stars.
+
+[[!img size=1024x blog/pics/lamp/front.jpg alt="front view of lit lamp beside a bookcase"]]
+

add
diff --git a/blog/pics/lamp/front.jpg b/blog/pics/lamp/front.jpg
new file mode 100644
index 00000000..3a9ddfe2
Binary files /dev/null and b/blog/pics/lamp/front.jpg differ
diff --git a/blog/pics/lamp/rear.jpg b/blog/pics/lamp/rear.jpg
new file mode 100644
index 00000000..04a1fd89
Binary files /dev/null and b/blog/pics/lamp/rear.jpg differ
diff --git a/blog/pics/lamp/wastful.jpg b/blog/pics/lamp/wastful.jpg
new file mode 100644
index 00000000..8ffefeee
Binary files /dev/null and b/blog/pics/lamp/wastful.jpg differ

Added a comment: still shorter…
diff --git a/blog/entry/turing_complete_version_numbers/comment_1_218d94300cfd331f4cbd3e004f73ef16._comment b/blog/entry/turing_complete_version_numbers/comment_1_218d94300cfd331f4cbd3e004f73ef16._comment
new file mode 100644
index 00000000..cc4de122
--- /dev/null
+++ b/blog/entry/turing_complete_version_numbers/comment_1_218d94300cfd331f4cbd3e004f73ef16._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="jon+joeyh@58e0bb898cec29edb297cf4a4a52efd862bef676"
+ nickname="jon+joeyh"
+ avatar="http://cdn.libravatar.org/avatar/7a82c206030ba192f78d073eaa43cdc5"
+ subject="still shorter…"
+ date="2019-09-30T09:54:48Z"
+ content="""
+that \"hello world\" is still shorter than this ludicrous thing
+
+acorn 6.2.1+ds+~0.4.0+~4.0.0+really4.0.0+~1.0.0+~5.0.1+ds+~1.7.0+ds+~0.1.1+~0.3.1+~0.2.0+~0.1.0+~0.3.0+~0.3.0-5
+(<https://bugs.debian.org/940708>)
+
+— [Jon](https://jmtd.net)
+"""]]

poll vote (watched it all, liked it)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index c171f8ae..1717fcdf 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 58 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 59 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

blog update
diff --git a/blog/entry/turing_complete_version_numbers.mdwn b/blog/entry/turing_complete_version_numbers.mdwn
new file mode 100644
index 00000000..2d642ac6
--- /dev/null
+++ b/blog/entry/turing_complete_version_numbers.mdwn
@@ -0,0 +1,35 @@
+A quick standard for when you want to embed an arbitrary program in the
+version number of your program.
+
+	2 	increment the data pointer (to point to the next cell to the right).
+	3 	decrement the data pointer (to point to the next cell to the left).
+	+ 	increment (increase by one) the byte at the data pointer.
+	- 	decrement (decrease by one) the byte at the data pointer.
+	. 	output the byte at the data pointer.
+	4 	accept one byte of input, storing its value in the byte at the data pointer.
+	6 	if the byte at the data pointer is zero, then instead of moving the instruction pointer forward to the next command, jump it forward to the command after the matching 9 command.
+	9 	if the byte at the data pointer is nonzero, then instead of moving the instruction pointer forward to the next command, jump it back to the command after the matching 6 command. 
+
+This is simply [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck)
+with operators that are legal in (Debian) version numbers kept as-is,
+and some numbers replacing the rest.
+
+Note that all other operators are ignored as usual. In particular, 1 and 8 are ignored,
+which make it easy to build version number programs that compare properly with past versions.
+And in some cases, adding 1 or 8 will be needed to make a particular program be a properly
+formatted version number.
+
+For example, an infinite loop version number is:
+
+	1+69
+
+A nice short hello world is:
+
+	1+6-6336+6-8-1-29-6333999222-92-1.1-1-1-8.2.8.2.3333-1.3+1.22222.2.33.3-1.1
+
+Licensing: Yes, there should also be a way to embed a license in a version ...
+Oh, I mean to say, the Wikipedia excerpt above is CC-BY-SA, and 
+the hello world is based on
+<https://esolangs.org/wiki/Hello_world_program_in_esoteric_languages>
+
+Previously: [[a_brainfuck_monad]]

poll vote (watched some, boring)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index af75f617..c171f8ae 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 58 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 58 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

Added a comment
diff --git a/blog/entry/how_to_detect_chef/comment_2_bf90645fd0e419b7c83ae89d78ad4e18._comment b/blog/entry/how_to_detect_chef/comment_2_bf90645fd0e419b7c83ae89d78ad4e18._comment
new file mode 100644
index 00000000..58005cdf
--- /dev/null
+++ b/blog/entry/how_to_detect_chef/comment_2_bf90645fd0e419b7c83ae89d78ad4e18._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="oz@fa83dac6e37245c88f2e67cd2a590df799bf36e9"
+ nickname="oz"
+ avatar="http://cdn.libravatar.org/avatar/0a6f759ed6dcc27727ae0b70f430d00d"
+ subject="comment 2"
+ date="2019-09-23T16:28:42Z"
+ content="""
+Thanks for caring.
+"""]]

Added a comment: You are a monster.
diff --git a/blog/entry/how_to_detect_chef/comment_1_2f31ba7257e4c09d513c314bf7d35d48._comment b/blog/entry/how_to_detect_chef/comment_1_2f31ba7257e4c09d513c314bf7d35d48._comment
new file mode 100644
index 00000000..7ba7d831
--- /dev/null
+++ b/blog/entry/how_to_detect_chef/comment_1_2f31ba7257e4c09d513c314bf7d35d48._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="ThirteenthLetter"
+ avatar="http://cdn.libravatar.org/avatar/217043e0fd7a23e751cbd9d0eeac594f"
+ subject="You are a monster."
+ date="2019-09-22T19:32:55Z"
+ content="""
+Open source is a principle, an ideal, and you pee all over it in the name of enforcing a political consensus you couldn't have cared less about four years ago. You should not be permitted near a computer. But hey, I'm sure you'll get plenty of Twitter likes and Reddit upvotes for throwing open software in the trash, so I guess that makes up for it.
+"""]]

poll vote (watched it all, liked it)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index 2e2e824a..af75f617 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 57 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 58 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

poll vote (watched it all, liked it)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index cea2a0a7..2e2e824a 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 56 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 57 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

blog update
diff --git a/blog/entry/how_to_detect_chef.mdwn b/blog/entry/how_to_detect_chef.mdwn
new file mode 100644
index 00000000..66b37fae
--- /dev/null
+++ b/blog/entry/how_to_detect_chef.mdwn
@@ -0,0 +1,12 @@
+If you want your program to detect when it's being run by chef, here's
+one way to do that.
+
+	sleep 1 while $ENV{PATH} =~ m#chef[^:]+/bin#;
+
+This works because Chef's `shell_out` adds `Gem.bindir` to `PATH`,
+which is something like `/opt/chefdk/embedded/bin`.
+
+You may want to delete the "sleep", which will make it run faster.
+
+Would I or anyone ever really do this? Chef Inc's management seems determined
+to test the question, don't they.

poll vote (watched it all, liked it)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index ca5e8c10..cea2a0a7 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 55 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 56 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

poll vote (watched it all, liked it)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index 3004ce97..ca5e8c10 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 54 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 55 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]