Recent changes to this wiki:

response
diff --git a/blog/entry/censored_Amazon_review_of_Sandisk_Ultra_32GB_Micro_SDHC_Card/comment_2_64a2d2cdb13c9696aaf2cb2066858c42._comment b/blog/entry/censored_Amazon_review_of_Sandisk_Ultra_32GB_Micro_SDHC_Card/comment_2_64a2d2cdb13c9696aaf2cb2066858c42._comment
new file mode 100644
index 00000000..d92a513b
--- /dev/null
+++ b/blog/entry/censored_Amazon_review_of_Sandisk_Ultra_32GB_Micro_SDHC_Card/comment_2_64a2d2cdb13c9696aaf2cb2066858c42._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2018-09-22T16:48:39Z"
+ content="""
+f3 does not detect the card as a fake. Although it did have a write failure
+half way through the scan, perhaps due to overheating. Or due to a low
+quality though full capacity flash chip used in a fake.
+
+And I could be wrong about that, despite the other indications. But a
+reviewer can of course be wrong about anything, that's not a reason to
+censor their review.
+"""]]

response
diff --git a/blog/entry/usb_drives_with_no_phantom_load/comment_12_2f03fdccbb5aebf54aa96a1ecfa151e0._comment b/blog/entry/usb_drives_with_no_phantom_load/comment_12_2f03fdccbb5aebf54aa96a1ecfa151e0._comment
new file mode 100644
index 00000000..a5ebb937
--- /dev/null
+++ b/blog/entry/usb_drives_with_no_phantom_load/comment_12_2f03fdccbb5aebf54aa96a1ecfa151e0._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""Re: Relay questions"""
+ date="2018-09-22T15:56:00Z"
+ content="""
+Yes, it's a good old fashioned relay, but it's under the computer's control.
+
+For example, this relay <https://www.sparkfun.com/products/13815> can be
+controlled by a GPIO port, consumes 0.6 watts of power to run
+and can switch 15 amps of AC current. I'm happily using several of them for
+other projects.
+
+My USB hub is actually powered by 24V DC, which comes from my solar charge
+controller's load port, which is also switched by computer control. That
+line also powers a more beefy 24V industrial relay that I had lying
+around, which can switch a lot more power but does consume 5 watts when
+run. I'll probably downgrade that relay at some point but an extra 5 watts
+when the drives are running is not a big deal.
+"""]]

Added a comment: Relay questions
diff --git a/blog/entry/usb_drives_with_no_phantom_load/comment_11_6e27f5918d7fd75f436ca8af81862738._comment b/blog/entry/usb_drives_with_no_phantom_load/comment_11_6e27f5918d7fd75f436ca8af81862738._comment
new file mode 100644
index 00000000..3475972a
--- /dev/null
+++ b/blog/entry/usb_drives_with_no_phantom_load/comment_11_6e27f5918d7fd75f436ca8af81862738._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="max@b5056edb4ef368a70ed36cec08d6d819d418872f"
+ nickname="max"
+ avatar="http://cdn.libravatar.org/avatar/cfa51855bbf2842e7ddce18aea1947ea"
+ subject="Relay questions"
+ date="2018-09-22T00:58:00Z"
+ content="""
+When you mention relay, do you mean the electromechanical devices? If so, do you measure the current consumption of the relay coil when it's energized?  
+
+Also, what is the relay doing for you if it's manually actuated? Is it in place for future automation? It seems the relay could otherwise safely be a regular mechanical switch in this relatively low power application.
+"""]]

Added a comment
diff --git a/blog/entry/censored_Amazon_review_of_Sandisk_Ultra_32GB_Micro_SDHC_Card/comment_1_068ff7fa9167a9887f5d73b696f0141a._comment b/blog/entry/censored_Amazon_review_of_Sandisk_Ultra_32GB_Micro_SDHC_Card/comment_1_068ff7fa9167a9887f5d73b696f0141a._comment
new file mode 100644
index 00000000..4ee92b4d
--- /dev/null
+++ b/blog/entry/censored_Amazon_review_of_Sandisk_Ultra_32GB_Micro_SDHC_Card/comment_1_068ff7fa9167a9887f5d73b696f0141a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="anarcat"
+ avatar="http://cdn.libravatar.org/avatar/4ad594c1e13211c1ad9edb81ce5110b7"
+ subject="comment 1"
+ date="2018-09-21T14:06:28Z"
+ content="""
+Those things are a plague... It's surprising how many cards are fake! I've been maintaining the [f3 package](https://tracker.debian.org/f3) in Debian for a bit now and I've tested it against a few keys. Some show up as fake, but I'm pretty sure it misses a few. I'm curious to see what it would make of your key.
+
+This is one of the reasons I don't buy at Amazon (anymore): on top of horrible worker conditions, returns are hard or impossible to carry out. At the corner store, I can and do go back and tell them their stuff is crap, and they actually care about fixing that because customers are in their face and won't come back if they don't fix it. :)
+"""]]

updated
diff --git a/blog/entry/usb_drives_with_no_phantom_load.mdwn b/blog/entry/usb_drives_with_no_phantom_load.mdwn
index 1f28a99b..cea81916 100644
--- a/blog/entry/usb_drives_with_no_phantom_load.mdwn
+++ b/blog/entry/usb_drives_with_no_phantom_load.mdwn
@@ -45,6 +45,7 @@ The `sleep 20` is a bit unfortunate, it seems that it can take a few seconds for
 the drive to power up enough for the kernel to see it, and so without that the
 mount can fail, leaving the drive powered on indefinitely. Seems there
 ought to be a way to declare an additional dependency and avoid needing that sleep?
+Update: See my comment below for a better way.
 
 Finally, the automount unit for the drive, media-joey-passport.automount:
 
diff --git a/blog/entry/usb_drives_with_no_phantom_load/comment_10_7ba06f3deb9a7a5aa9750014e65a0e3f._comment b/blog/entry/usb_drives_with_no_phantom_load/comment_10_7ba06f3deb9a7a5aa9750014e65a0e3f._comment
new file mode 100644
index 00000000..4e3a743b
--- /dev/null
+++ b/blog/entry/usb_drives_with_no_phantom_load/comment_10_7ba06f3deb9a7a5aa9750014e65a0e3f._comment
@@ -0,0 +1,34 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 10"""
+ date="2018-09-19T18:46:30Z"
+ content="""
+@grawity hmm, that's promising, the sysfs uvent file did not trigger udev,
+but "udevadm trigger --action=remove /sys/class/block/sdb1" does
+remove links to it in /dev/disk/by-label/, though /dev/sdb1 remains
+present.
+
+And yeah, systemd's dependency on the device does work properly then,
+it delays mounting until the drive has spun up.
+
+Ah, even easier, "udevadm trigger --action=remove /dev/disk/by-label/passport"
+does the same thing without needing to find the sysfs path.
+
+So, I've changed the service file for the hub port to look like this:
+
+	[Unit]
+	Description=Startech usb hub port 4
+	PartOf=media-joey-passport.mount
+	[Service]
+	Type=oneshot
+	RemainAfterExit=true
+	ExecStart=/usr/sbin/uhubctl -a on -p 4
+	ExecStop=/bin/sh -c 'uhubctl -a off -p 4 ; udevadm trigger --action=remove /dev/disk/by-label/passport || true'
+
+/bin/sh actually needed now since a failure of udevadm due to the 
+label not existing etc needs to be ignored.
+
+Kind of ugly that the service file for the hub port needs to know the label
+of the disk, but since I'm generating these service files not using systemd's
+limited templates, but from Haskell code, it was easy to extend to include that.
+"""]]

blog update
diff --git a/blog/entry/censored_Amazon_review_of_Sandisk_Ultra_32GB_Micro_SDHC_Card.mdwn b/blog/entry/censored_Amazon_review_of_Sandisk_Ultra_32GB_Micro_SDHC_Card.mdwn
new file mode 100644
index 00000000..801bfad2
--- /dev/null
+++ b/blog/entry/censored_Amazon_review_of_Sandisk_Ultra_32GB_Micro_SDHC_Card.mdwn
@@ -0,0 +1,23 @@
+> ★ counterfeits in amazon pipeline
+> 
+> The 32 gb card I bought here at Amazon turned out to be fake. Within days I was
+> getting read errors, even though the card was still mostly empty.
+> 
+> The logo is noticably blurry compared with a 32 gb card purchased elsewhere.
+> Also, the color of the grey half of the card is subtly wrong, and the lettering
+> is subtly wrong.
+> 
+> Amazon apparently has counterfiet stock in their pipeline, google "amazon
+> counterfiet" for more.
+
+You will not find this review on 
+[Sandisk Ultra 32GB Micro SDHC UHS-I Card with Adapter - 98MB/s U1 A1 - SDSQUAR-032G-GN6MA ](https://www.amazon.com/gp/product/B073JWXGNT/ref=oh_aui_detailpage_o02_s01?ie=UTF8&psc=1)
+because it was rejected. As far as I can tell my review violates none of Amazon's 
+[posted guidelines](http://www.amazon.com/review-guidelines).
+But it's specific about how to tell this card is counterfeit, and it mentions 
+[a](https://petapixel.com/2018/05/31/beware-amazon-still-sells-counterfeit-memory-cards/)
+[real](https://www.theatlantic.com/technology/archive/2018/04/amazon-may-have-a-counterfeit-problem/558482/) 
+[and](https://www.engadget.com/2018/05/31/fulfilled-by-amazon-counterfeit-fake/)
+[ongoing](https://www.axios.com/amazon-counterfeit-fake-products-8dedb8f9-4828-4c80-b7f7-76a724ad117e.html)
+[issue](https://www.diyphotography.net/psa-fake-sandisk-memory-cards-are-everywhere-including-amazon/)
+that Amazon clearly wants to cover up.

Added a comment: With unison
diff --git a/blog/entry/locking_down_ssh_authorized_keys/comment_3_0a9e26f4882326f822388833ea8e1d49._comment b/blog/entry/locking_down_ssh_authorized_keys/comment_3_0a9e26f4882326f822388833ea8e1d49._comment
new file mode 100644
index 00000000..9eab623b
--- /dev/null
+++ b/blog/entry/locking_down_ssh_authorized_keys/comment_3_0a9e26f4882326f822388833ea8e1d49._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~cassou"
+ nickname="cassou"
+ avatar="http://cdn.libravatar.org/avatar/b393bcb0caac9d23ede8fbacf2990f69469c22bd4a6a60fa4ff7bf51e7273c1f"
+ subject="With unison"
+ date="2018-09-12T08:56:25Z"
+ content="""
+Add that to your authorized_keys file on the host to restrict usage of the key to unison:
+
+    # Look at manpage sshd(8) for more information on options
+    command=\"unison -server\",restrict ssh-rsa ...the key...
+
+"""]]

Added a comment
diff --git a/blog/entry/usb_drives_with_no_phantom_load/comment_9_c4bdf81496c5f507821a26aa5a8e98ea._comment b/blog/entry/usb_drives_with_no_phantom_load/comment_9_c4bdf81496c5f507821a26aa5a8e98ea._comment
new file mode 100644
index 00000000..ff68d62e
--- /dev/null
+++ b/blog/entry/usb_drives_with_no_phantom_load/comment_9_c4bdf81496c5f507821a26aa5a8e98ea._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="grawity@2ea26be48562f66fcb9b66307da72b1e2e37453f"
+ nickname="grawity"
+ avatar="http://cdn.libravatar.org/avatar/7003e967f47003bae82966aa373de8ef"
+ subject="comment 9"
+ date="2018-09-10T04:44:37Z"
+ content="""
+> udev keeps the disk device files in place. Attempting to access the device then leads to an IO error, and then udev notices the device is gone and removes its files
+
+Udev maintains `/dev/disk/*` symlinks and systemd's .device units, but it relies 100% on receiving the kernel's uevents to trigger the maintenance. (For that matter, the actual `/dev/sd*` nodes are created by the kernel itself via devtmpfs, not by udev anymore.)
+
+Therefore that's a kernel problem. (Or... maybe just the way uhubctl works? Does the kernel even _know_ that the port is now powered off? I think it doesn't, because uhubctl sort of bypasses the whole USB stack.)
+
+I wonder what happens if you try to fake a kernel uevent using `udevadm trigger --action=remove /sys/<sysfs_path>` after the poweroff. (Or `echo remove > /sys/<sysfs_path>/uevent`.) That won't remove the device from kernel, just poke udev about its supposed removal.
+
+> https://www.spinics.net/lists/linux-usb/msg157413.html
+
+Aha. That's unfortunate. (Even though \"the API can always be enlarged\" I wouldn't hold my breath...) 
+"""]]

Added a comment
diff --git a/blog/entry/usb_drives_with_no_phantom_load/comment_8_923f2e7da8fae9ebcb4417a663b15886._comment b/blog/entry/usb_drives_with_no_phantom_load/comment_8_923f2e7da8fae9ebcb4417a663b15886._comment
new file mode 100644
index 00000000..1e82e86a
--- /dev/null
+++ b/blog/entry/usb_drives_with_no_phantom_load/comment_8_923f2e7da8fae9ebcb4417a663b15886._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="grawity@2ea26be48562f66fcb9b66307da72b1e2e37453f"
+ nickname="grawity"
+ avatar="http://cdn.libravatar.org/avatar/7003e967f47003bae82966aa373de8ef"
+ subject="comment 8"
+ date="2018-09-10T04:42:56Z"
+ content="""
+> In systemd unit this line probably doesn't mean what you seem to think it does
+
+No, it means exactly that. Multiple commands in ExecStart= separated by a standalone `;` token have been supported for a very long time. (Though they don't always make sense logically – e.g. if you have Type=forking, which command is supposed to be the daemon? why aren't they ExecStartPre's instead? – but in a `Type=oneshot` this usage is fine.)
+"""]]

comment
diff --git a/blog/entry/usb_drives_with_no_phantom_load/comment_7_cd5572bcc465858890cf129f0b218844._comment b/blog/entry/usb_drives_with_no_phantom_load/comment_7_cd5572bcc465858890cf129f0b218844._comment
new file mode 100644
index 00000000..2c40ea0e
--- /dev/null
+++ b/blog/entry/usb_drives_with_no_phantom_load/comment_7_cd5572bcc465858890cf129f0b218844._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 7"""
+ date="2018-09-09T22:28:23Z"
+ content="""
+<https://www.spinics.net/lists/linux-usb/msg157413.html>
+"""]]

comments
diff --git a/blog/entry/usb_drives_with_no_phantom_load/comment_5_15393a74da8d1fd466a65a11ad284023._comment b/blog/entry/usb_drives_with_no_phantom_load/comment_5_15393a74da8d1fd466a65a11ad284023._comment
new file mode 100644
index 00000000..b456a4dc
--- /dev/null
+++ b/blog/entry/usb_drives_with_no_phantom_load/comment_5_15393a74da8d1fd466a65a11ad284023._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""re: systemd unit syntax error"""
+ date="2018-09-09T16:24:47Z"
+ content="""
+No, my syntax is correct and works. According to systemd.syntax(7):
+
+	Empty lines and lines starting with "#" or ";" are ignored, which 
+	may be used for commenting.
+
+Nothing about use of those characters further into a line.
+
+(Some of systemd's docs do contain examples of using sh -c and escaping
+semicolons, so perhaps this has changed since earlier versions. Multiple
+ExecStart lines is another way to run multiple commands.)
+
+But in fact, the example I gave works. You can see the 20 second delay in the
+journal:
+
+	Sep 09 12:32:24 honeybee systemd[1]: Starting Startech usb hub port 4...
+	Sep 09 12:32:26 honeybee uhubctl[18819]: Current status for hub 2-1 [0409:005a, USB 2.00, 4 ports]
+	Sep 09 12:32:26 honeybee uhubctl[18819]:   Port 4: 0000 off
+	Sep 09 12:32:26 honeybee uhubctl[18819]: Sent power on request
+	Sep 09 12:32:26 honeybee uhubctl[18819]: New status for hub 2-1 [0409:005a, USB 2.00, 4 ports]
+	Sep 09 12:32:26 honeybee uhubctl[18819]:   Port 4: 0101 power connect [0480:0200]
+	Sep 09 12:32:46 honeybee systemd[1]: Started Startech usb hub port 4.
+"""]]
diff --git a/blog/entry/usb_drives_with_no_phantom_load/comment_6_c6dbe656e101c3097d73b1aeed76c173._comment b/blog/entry/usb_drives_with_no_phantom_load/comment_6_c6dbe656e101c3097d73b1aeed76c173._comment
new file mode 100644
index 00000000..bfc300d1
--- /dev/null
+++ b/blog/entry/usb_drives_with_no_phantom_load/comment_6_c6dbe656e101c3097d73b1aeed76c173._comment
@@ -0,0 +1,37 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 6"""
+ date="2018-09-09T16:49:36Z"
+ content="""
+@grawity, I tried the Requires on the device label,
+but it does not avoid the problem:
+
+	root@honeybee:/etc/systemd/system>ls /media/joey/archive-12
+	ls: cannot open directory '/media/joey/archive-12': No such device
+
+	Sep 09 13:33:50 honeybee systemd[1]: Starting Startech usb hub port 3...
+	Sep 09 13:33:50 honeybee uhubctl[23224]: Current status for hub 2-1 [0409:005a, USB 2.00, 4 ports]
+	Sep 09 13:33:50 honeybee uhubctl[23224]:   Port 3: 0000 off
+	Sep 09 13:33:50 honeybee uhubctl[23224]: Sent power on request
+	Sep 09 13:33:50 honeybee uhubctl[23224]: New status for hub 2-1 [0409:005a, USB 2.00, 4 ports]
+	Sep 09 13:33:50 honeybee uhubctl[23224]:   Port 3: 0101 power connect [1058:25ee]
+	Sep 09 13:33:50 honeybee systemd[1]: Started Startech usb hub port 3.
+	Sep 09 13:33:50 honeybee systemd[1]: Mounting archive-12...
+	Sep 09 13:33:50 honeybee systemd[1]: media-joey-archive\x2d12.mount: Mount process exited, code=exited status=32
+	Sep 09 13:33:50 honeybee systemd[1]: media-joey-archive\x2d12.mount: Failed with result 'exit-code'.
+	Sep 09 13:33:50 honeybee systemd[1]: Failed to mount archive-12.
+
+Ah, I think I see why. After the usb port is shut down, udev keeps the disk
+device files in place. Attempting to access the device then leads to an IO error,
+and *then* udev notices the device is gone and removes its files. So
+systemd's dependencies are working, but it's seeing stale information.
+
+Perhaps this is a bug in udev, that it's not noticing the usb port powered
+down. It seems to not get any kernel event for it at all, according to
+`udevadm monitor`.
+
+I thought maybe a different workaround would be to dd one byte from the
+disk after powering it down, or `udevadm trigger` the device manually.
+Unfortunately, the kernel auto-powers the usb port back up when either of
+those is done. So I'll stick with the sleep for now..
+"""]]

Added a comment: systemd unit syntax error
diff --git a/blog/entry/usb_drives_with_no_phantom_load/comment_4_f514a67a0e4e84e5a9ca647bbc8c0b19._comment b/blog/entry/usb_drives_with_no_phantom_load/comment_4_f514a67a0e4e84e5a9ca647bbc8c0b19._comment
new file mode 100644
index 00000000..a650d0b2
--- /dev/null
+++ b/blog/entry/usb_drives_with_no_phantom_load/comment_4_f514a67a0e4e84e5a9ca647bbc8c0b19._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="mk.fraggod@a2e97043e01bcf7237d068482b83a6cb9e179ca0"
+ nickname="mk.fraggod"
+ avatar="http://cdn.libravatar.org/avatar/db0d5b15da76246bed0ba3c253b5ea82"
+ subject="systemd unit syntax error"
+ date="2018-09-09T13:40:08Z"
+ content="""
+In systemd unit this line probably doesn't mean what you seem to think it does:
+
+    ExecStart=/usr/sbin/uhubctl -a on -p 4 ; /bin/sleep 20
+
+\"/bin/sleep 20\" there is probably irrelevant - a comment in an ini file.
+
+Unless debian patches systemd that way, whole ExecStart= line isn't passed to shell anyway, so if that part was passed to command, it'd probably just exit on parsing options.
+
+Something like this should work though:
+
+    ExecStart=/bin/bash -c \"uhubctl -a on -p 4 ; /bin/sleep 20\"
+
+"""]]

Added a comment: Monitoring USB drive health in Linux
diff --git a/blog/entry/usb_drives_with_no_phantom_load/comment_3_3078a8364227e91bd33e78acd75cd079._comment b/blog/entry/usb_drives_with_no_phantom_load/comment_3_3078a8364227e91bd33e78acd75cd079._comment
new file mode 100644
index 00000000..23950f45
--- /dev/null
+++ b/blog/entry/usb_drives_with_no_phantom_load/comment_3_3078a8364227e91bd33e78acd75cd079._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="Abishek_Muthian"
+ avatar="http://cdn.libravatar.org/avatar/1fe2acd0e7273426630dc7f02d05c9ea"
+ subject="Monitoring USB drive health in Linux"
+ date="2018-09-09T05:48:07Z"
+ content="""
+Hi Joey,
+
+Could you also elaborate on how you monitor your USB drive health, considering kernel doesn't seem to allow SAT ATA passthrough commands when using 'uas' driver.
+"""]]

Added a comment
diff --git a/blog/entry/usb_drives_with_no_phantom_load/comment_2_7dc2b45f692c775ea1675e9bac771fe6._comment b/blog/entry/usb_drives_with_no_phantom_load/comment_2_7dc2b45f692c775ea1675e9bac771fe6._comment
new file mode 100644
index 00000000..c7f59fa7
--- /dev/null
+++ b/blog/entry/usb_drives_with_no_phantom_load/comment_2_7dc2b45f692c775ea1675e9bac771fe6._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="grawity@2ea26be48562f66fcb9b66307da72b1e2e37453f"
+ nickname="grawity"
+ avatar="http://cdn.libravatar.org/avatar/7003e967f47003bae82966aa373de8ef"
+ subject="comment 2"
+ date="2018-09-08T19:57:59Z"
+ content="""
+As a side note, it sounds like you have several near-identical \"hub-port-X\" units (or at least they will become near-identical if the previous comment's suggestion with StopWhenUnneeded=true works out). These could be collapsed into a template `startech-usb-hub@.service` which uses `%i` in place of the port number everywhere.
+"""]]

Added a comment
diff --git a/blog/entry/usb_drives_with_no_phantom_load/comment_1_ba9b3c3ee0aa4ff7c1c79ea96197dd02._comment b/blog/entry/usb_drives_with_no_phantom_load/comment_1_ba9b3c3ee0aa4ff7c1c79ea96197dd02._comment
new file mode 100644
index 00000000..41994e49
--- /dev/null
+++ b/blog/entry/usb_drives_with_no_phantom_load/comment_1_ba9b3c3ee0aa4ff7c1c79ea96197dd02._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="grawity@2ea26be48562f66fcb9b66307da72b1e2e37453f"
+ nickname="grawity"
+ avatar="http://cdn.libravatar.org/avatar/7003e967f47003bae82966aa373de8ef"
+ subject="comment 1"
+ date="2018-09-08T19:50:26Z"
+ content="""
+> Seems there ought to be a way to declare an additional dependency and avoid needing that sleep?
+
+Your .mount unit can use `Requires=dev-disk-by\x2dlabel-passport.device`.
+
+(Actually I was quite sure that .mount units automatically depend on their What= device in any case, but I guess only an After= is implicit but a Requires= isn't.)
+
+> The combination of PartOf
+
+I think it would be simpler to use `StopWhenUnneeded=yes` in the .service (once you have the aforementioned Requires=dev-disk in your .mount unit). Such a combination _might_ be more reliable as well.
+"""]]

blog update
diff --git a/blog/entry/usb_drives_with_no_phantom_load.mdwn b/blog/entry/usb_drives_with_no_phantom_load.mdwn
new file mode 100644
index 00000000..1f28a99b
--- /dev/null
+++ b/blog/entry/usb_drives_with_no_phantom_load.mdwn
@@ -0,0 +1,65 @@
+For a long time I've not had any network attached storage at home, because
+it's offgrid and power budget didn't allow it. But now I have 16 
+terabytes of network attached storage, that uses no power at all when
+it's not in use, and automatically spins up on demand.
+
+I used a USB hub with per-port power control. But even with a USB drive's
+port powered down, there's a parasitic draw of around 3 watts per drive.
+Not a lot, but with 4 drives that's more power wasted than leaving a couple
+of ceiling lights on all the time. So I put all the equipment behind a
+relay too, so it can be fully powered down.
+
+I'm using systemd for automounting the drives, and have it configured to
+power a drive's USB port on and off as needed using
+[uhubctl](https://github.com/mvp/uhubctl).
+This was kind of tricky to work out how to do, but it works very well.
+
+Here's the mount unit for a drive, media-joey-passport.mount:
+
+	[Unit]
+	Description=passport
+	Requires=startech-hub-port-4.service
+	After=startech-hub-port-4.service
+	[Mount]
+	Options=noauto
+	What=/dev/disk/by-label/passport
+	Where=/media/joey/passport
+
+That's on port 4 of the USB hub, the startech-hub-port-4.service unit
+file is this:
+
+	[Unit]
+	Description=Startech usb hub port 4
+	PartOf=media-joey-passport.mount
+	[Service]
+	Type=oneshot
+	RemainAfterExit=true
+	ExecStart=/usr/sbin/uhubctl -a on -p 4 ; /bin/sleep 20
+	ExecStop=/usr/sbin/uhubctl -a off -p 4
+
+The combination of PartOf with Requires and After in these units makes 
+systemd start the port 4 service before mounting the drive, and 
+stop it after unmounting. This was the hardest part to work out.
+
+The `sleep 20` is a bit unfortunate, it seems that it can take a few seconds for
+the drive to power up enough for the kernel to see it, and so without that the
+mount can fail, leaving the drive powered on indefinitely. Seems there
+ought to be a way to declare an additional dependency and avoid needing that sleep?
+
+Finally, the automount unit for the drive, media-joey-passport.automount:
+
+	[Unit]
+	Description=Automount passport
+	[Automount]
+	Where=/media/joey/passport
+	TimeoutIdleSec=300
+	[Install]
+	WantedBy=multi-user.target
+
+The TimeoutIdleSec makes it unmount after around 5 minutes of not being used,
+and then its USB port gets powered off.
+
+I decided to not automate the relay as part of the above, instead I
+typically turn it on for 5 hours or so, and use the storage whenever I want
+during that window. One advantage to that is cron jobs can't spin up
+the drives in the early morning hours.

Added a comment: Thank you
diff --git a/blog/entry/camping_Roan_highlands/comment_2_2bc65c200a1709050fe42361ffbd658d._comment b/blog/entry/camping_Roan_highlands/comment_2_2bc65c200a1709050fe42361ffbd658d._comment
new file mode 100644
index 00000000..b0ec61fc
--- /dev/null
+++ b/blog/entry/camping_Roan_highlands/comment_2_2bc65c200a1709050fe42361ffbd658d._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="edhamilton9@1f08806bf5517489acd14136b49e97b63fb63519"
+ nickname="edhamilton9"
+ avatar="http://cdn.libravatar.org/avatar/a78e4861017c7e48a0e77174de2b25c8"
+ subject="Thank  you"
+ date="2018-08-27T12:09:20Z"
+ content="""
+Hi. I have Planet Debian in my feedreader, which is where I came across your blog. 
+My wallpaper right now is a sunset taken from Roan Mountain. I don't know where I found the picture. 
+It looks like a beautiful place. Thanks for posting it.
+
+Ed H
+"""]]

Added a comment
diff --git a/blog/entry/camping_Roan_highlands/comment_1_d585b45c3a92c36953948271b65a96d1._comment b/blog/entry/camping_Roan_highlands/comment_1_d585b45c3a92c36953948271b65a96d1._comment
new file mode 100644
index 00000000..62a2c07a
--- /dev/null
+++ b/blog/entry/camping_Roan_highlands/comment_1_d585b45c3a92c36953948271b65a96d1._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="sarahnoce@733718de58a0b1196931cd960415c06b77e892b4"
+ nickname="sarahnoce"
+ avatar="http://cdn.libravatar.org/avatar/50b2128e90983e8e2df283fd25d3c12b"
+ subject="comment 1"
+ date="2018-08-26T18:28:35Z"
+ content="""
+beautiful, joey!
+"""]]

typo
diff --git a/blog/entry/camping_Roan_highlands.mdwn b/blog/entry/camping_Roan_highlands.mdwn
index 1fa6ffea..fefc7581 100644
--- a/blog/entry/camping_Roan_highlands.mdwn
+++ b/blog/entry/camping_Roan_highlands.mdwn
@@ -1,3 +1,3 @@
 [[!img pics/tentroan.jpg size=800x caption="small tent overlooking a big view"]]
 
-My second time camping the Roan highlads on the AT.
+My second time camping the Roan highlands on the AT.

scale
diff --git a/blog/entry/camping_Roan_highlands.mdwn b/blog/entry/camping_Roan_highlands.mdwn
index 541b3011..1fa6ffea 100644
--- a/blog/entry/camping_Roan_highlands.mdwn
+++ b/blog/entry/camping_Roan_highlands.mdwn
@@ -1,3 +1,3 @@
-[[!img pics/tentroan.jpg size=1024x caption="small tent overlooking a big view"]]
+[[!img pics/tentroan.jpg size=800x caption="small tent overlooking a big view"]]
 
 My second time camping the Roan highlads on the AT.

scale
diff --git a/blog/entry/camping_Roan_highlands.mdwn b/blog/entry/camping_Roan_highlands.mdwn
index e6fce217..541b3011 100644
--- a/blog/entry/camping_Roan_highlands.mdwn
+++ b/blog/entry/camping_Roan_highlands.mdwn
@@ -1,3 +1,3 @@
-[[!img pics/tentroan.jpg size=100x caption="small tent overlooking a big view"]]
+[[!img pics/tentroan.jpg size=1024x caption="small tent overlooking a big view"]]
 
 My second time camping the Roan highlads on the AT.

scale
diff --git a/blog/entry/camping_Roan_highlands.mdwn b/blog/entry/camping_Roan_highlands.mdwn
index b3547916..e6fce217 100644
--- a/blog/entry/camping_Roan_highlands.mdwn
+++ b/blog/entry/camping_Roan_highlands.mdwn
@@ -1,3 +1,3 @@
-[[!img pics/tentroan.jpg width=100x caption="small tent overlooking a big view"]]
+[[!img pics/tentroan.jpg size=100x caption="small tent overlooking a big view"]]
 
 My second time camping the Roan highlads on the AT.

blog update
diff --git a/blog/entry/camping_Roan_highlands.mdwn b/blog/entry/camping_Roan_highlands.mdwn
new file mode 100644
index 00000000..b3547916
--- /dev/null
+++ b/blog/entry/camping_Roan_highlands.mdwn
@@ -0,0 +1,3 @@
+[[!img pics/tentroan.jpg width=100x caption="small tent overlooking a big view"]]
+
+My second time camping the Roan highlads on the AT.
diff --git a/blog/pics/tentroan.jpg b/blog/pics/tentroan.jpg
new file mode 100644
index 00000000..c59fc16c
Binary files /dev/null and b/blog/pics/tentroan.jpg differ

blog update
diff --git a/blog/entry/Dear_Ad_Networks.mdwn b/blog/entry/Dear_Ad_Networks.mdwn
new file mode 100644
index 00000000..934542bc
--- /dev/null
+++ b/blog/entry/Dear_Ad_Networks.mdwn
@@ -0,0 +1,11 @@
+In 1 week, I plan to benchmark all your advertisment delivery systems from
+IP address block 184.20/16.
+
+Please note attached
+[Intel microcode license](https://perens.com/2018/08/22/new-intel-microcode-license-restriction-is-not-acceptable/)
+may apply to your servers. If you don't want me benchmarking your 
+ad servers, simply blacklist my IP block now.
+
+Love, Joey
+
+PS The benchmarking will continue indefinitely.

ocracoke 2018
diff --git a/ocracode.mdwn b/ocracode.mdwn
index d15d2cbb..4586ea4a 100644
--- a/ocracode.mdwn
+++ b/ocracode.mdwn
@@ -117,3 +117,4 @@ describe your camping trip to Ocracoke.
 * [[2014|blog/entry/laptop_death]]
 * [[2015|ocracode/2015]]
 * [[2015|ocracode/2016]]
+* [[2018|ocracode/2018]]
diff --git a/ocracode/2018.mdwn b/ocracode/2018.mdwn
new file mode 100644
index 00000000..aac58829
--- /dev/null
+++ b/ocracode/2018.mdwn
@@ -0,0 +1,3 @@
+OBX1.1 P4/8/6 L7 SC5+++++db-c-- U1(no bugs)
+T0f0b0 R5wTst Bn-----b------m----- F++u+ SC+s+g10
+H---f0i3 V+++++s----m0 E++r--

typo
diff --git a/languages/discussion.mdwn b/languages/discussion.mdwn
index 96731bdb..45f17189 100644
--- a/languages/discussion.mdwn
+++ b/languages/discussion.mdwn
@@ -6,4 +6,4 @@ I know you mention JS. Though what about other 'languages' of the Web API puzzle
 Keep on hacking on Web applications Joey. You're very good at it. :)
 
 > Unlike English and Perl, HTML and CSS are not Turing complete
-> (barring horriible hacks), so they're not languages. --[[Joey]]
+> (barring horrible hacks), so they're not languages. --[[Joey]]

test
diff --git a/languages/discussion.mdwn b/languages/discussion.mdwn
index 7fe07891..96731bdb 100644
--- a/languages/discussion.mdwn
+++ b/languages/discussion.mdwn
@@ -5,5 +5,5 @@ I know you mention JS. Though what about other 'languages' of the Web API puzzle
 
 Keep on hacking on Web applications Joey. You're very good at it. :)
 
-> Unlike English and Perl, HTML and CSS are not Turing complete, so they're
-> not languages. --[[Joey]]
+> Unlike English and Perl, HTML and CSS are not Turing complete
+> (barring horriible hacks), so they're not languages. --[[Joey]]

typo
diff --git a/blog/entry/two_security_holes_and_a_new_library.mdwn b/blog/entry/two_security_holes_and_a_new_library.mdwn
index 2f92be0f..abaa505c 100644
--- a/blog/entry/two_security_holes_and_a_new_library.mdwn
+++ b/blog/entry/two_security_holes_and_a_new_library.mdwn
@@ -33,7 +33,7 @@ such private data, the confusion can result in private data being exposed.
 See [the_advisory](https://git-annex.branchable.com/security/CVE-2018-10857_and_CVE-2018-10859/)
 for details.
 
-Fixing this kind of security hoole is not necessarily easy, because we use
+Fixing this kind of security hole is not necessarily easy, because we use
 HTTP libraries, often via an API library, which may not give much
 control over following redirects. DNS rebinding attacks can be 
 used to defeat security checks, if the HTTP library doesn't expose 

RESTLESS
diff --git a/blog/entry/two_security_holes_and_a_new_library.mdwn b/blog/entry/two_security_holes_and_a_new_library.mdwn
index 317064bb..2f92be0f 100644
--- a/blog/entry/two_security_holes_and_a_new_library.mdwn
+++ b/blog/entry/two_security_holes_and_a_new_library.mdwn
@@ -14,6 +14,8 @@ remotes) that uses HTTP. And quite likely beyond git-annex to unrelated
 programs, but I'll let their developers talk about that. So quite a lot of
 people were involved in this behind the scenes.
 
+See also: [The RESTLESS Vulnerability: Non-Browser Based Cross-Domain HTTP Request Attacks](https://www.danieldent.com/blog/restless-vulnerability-non-browser-cross-domain-http-request-attacks/)
+
 And then there was the second security hole in git-annex, which took
 several days to notice, in collaboration with Daniel Dent. That one's
 potentially very nasty, allowing decryption of arbitrary gpg-encrypted

blog
diff --git a/blog/entry/two_security_holes_and_a_new_library.mdwn b/blog/entry/two_security_holes_and_a_new_library.mdwn
new file mode 100644
index 00000000..317064bb
--- /dev/null
+++ b/blog/entry/two_security_holes_and_a_new_library.mdwn
@@ -0,0 +1,61 @@
+For the past week and a half, I've been working on embargoed
+[security holes](https://git-annex.branchable.com/security/CVE-2018-10857_and_CVE-2018-10859/). 
+The embargo is over, and git-annex 6.20180626 has been
+[released](https://git-annex.branchable.com/news/security_fix_release/), 
+fixing those holes. I'm also announcing a new Haskell library, 
+[[code/http-client-restricted]], which could be used to avoid
+similar problems in other programs.
+
+Working in secret under a security embargo is mostly new to me, and I
+mostly don't like it, but it seems to have been the right call in this
+case. The first security hole I found in git-annex turned out to have a
+wider impact, affecting code in git-annex plugins (aka external special
+remotes) that uses HTTP. And quite likely beyond git-annex to unrelated
+programs, but I'll let their developers talk about that. So quite a lot of
+people were involved in this behind the scenes.
+
+And then there was the second security hole in git-annex, which took
+several days to notice, in collaboration with Daniel Dent. That one's
+potentially very nasty, allowing decryption of arbitrary gpg-encrypted
+files, although exploiting it would be hard. It logically
+followed from the first security hole, so it's good that the first
+security hole was under embagro long enough for us to think it all
+though.
+
+These security holes involved HTTP servers doing things to exploit
+clients that connect to them. For example, a HTTP server that a client asks
+for the content of a file stored on it can redirect to a file://
+on the client's disk, or to http://localhost/ or a private web server on
+the client's internal network. Once the client is tricked into downloading
+such private data, the confusion can result in private data being exposed.
+See [the_advisory](https://git-annex.branchable.com/security/CVE-2018-10857_and_CVE-2018-10859/)
+for details.
+
+Fixing this kind of security hoole is not necessarily easy, because we use
+HTTP libraries, often via an API library, which may not give much
+control over following redirects. DNS rebinding attacks can be 
+used to defeat security checks, if the HTTP library doesn't expose 
+the IP address it's connecting to.
+
+I faced this problem in git-annex's use of the Haskell
+[http-client](https://hackage.haskell.org/package/http-client/) library.
+So I had to write a new library, [[code/http-client-restricted]]. Thanks
+to the good design of the http-client library, particularly its Manager
+abstraction, my library extends it rather than needing to replace it,
+and can be used with any API library built on top of http-client.
+
+I get the impression that a lot of other language's HTTP libraries need
+to have similar things developed. Much like web browsers need to enforce
+same-origin policies, HTTP clients need to be able to reject certain
+redirects according to the security needs of the program using them.
+
+I kept a private journal while working on these security holes, and am
+publishing it now:
+
+* [day 1](https://git-annex.branchable.com/devblog/day_499__security_hole/)
+* [day 2](https://git-annex.branchable.com/devblog/day_500__security_hole_part_2/)
+* [day 3](https://git-annex.branchable.com/devblog/day_501__security_hole_part_3/)
+* [day 4](https://git-annex.branchable.com/devblog/day_502__security_hole_part_4/)
+* [day 5](https://git-annex.branchable.com/devblog/day_503__security_hole_part_5/)
+* [day 6](https://git-annex.branchable.com/devblog/day_504__security_hole_part_6/)
+* [day 7](https://git-annex.branchable.com/devblog/day_505__security_fix_release/)

new project
diff --git a/code.mdwn b/code.mdwn
index 1e8dec56..612043a0 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -15,9 +15,9 @@ The stuff that's swapped into my local cache at the moment.
 [[ikiwiki]]
 [[moreutils]]
 [[ikiwiki-hosting]]
-[[github-backup]]
 [[shell-monad]]
 [[reactive-banana-automation]]
+[[http-client-restricted]]
 [[easy-peasy-devicetree-squeezy]]
 [[scuttlebutt-types]]
 
@@ -33,6 +33,7 @@ In maintenance mode mostly, but I still have my hands in it somewhat.
 [[brainfuck-monad]]
 [[zxcvbn-c]]
 [[scroll]]
+[[github-backup]]
 
 ## Past projects
 
diff --git a/code/http-client-restricted.mdwn b/code/http-client-restricted.mdwn
new file mode 100644
index 00000000..4c47b212
--- /dev/null
+++ b/code/http-client-restricted.mdwn
@@ -0,0 +1,3 @@
+restricting the servers that http-client will use
+
+<http://hackage.haskell.org/package/http-client-restricted>

response
diff --git a/blog/entry/unifying_OS_installation_and_configuration_management/comment_2_cdf45b4ef0f72fdacba1cfeb6c3d3b09._comment b/blog/entry/unifying_OS_installation_and_configuration_management/comment_2_cdf45b4ef0f72fdacba1cfeb6c3d3b09._comment
new file mode 100644
index 00000000..c37bf6d7
--- /dev/null
+++ b/blog/entry/unifying_OS_installation_and_configuration_management/comment_2_cdf45b4ef0f72fdacba1cfeb6c3d3b09._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2018-06-13T14:21:30Z"
+ content="""
+Propellor tracks which OS's a property supports at the type level. So to
+add a new OS, you have to at least add the types for it.
+
+I imagine that UnixLike should cover Nixos well enough for most things,
+but perhaps there will be some places Nix diverges too much from standard
+unix practice for that to work, perhaps something to do with filesystem
+layout.
+
+If you look for "Arch Linux" in the git log you'll find a patch set that is
+a good example of the kind of changes you'll need to make.
+"""]]

Added a comment: NixOS Support
diff --git a/blog/entry/unifying_OS_installation_and_configuration_management/comment_1_d310c46c1581fa1c6807580d9a613364._comment b/blog/entry/unifying_OS_installation_and_configuration_management/comment_1_d310c46c1581fa1c6807580d9a613364._comment
new file mode 100644
index 00000000..a913cf6e
--- /dev/null
+++ b/blog/entry/unifying_OS_installation_and_configuration_management/comment_1_d310c46c1581fa1c6807580d9a613364._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="craige"
+ avatar="http://cdn.libravatar.org/avatar/64ac5816ea3a51347d1f699022d1fdc1"
+ subject="NixOS Support"
+ date="2018-06-13T06:50:28Z"
+ content="""
+G'day Joey. Loving this body of work. Thank you.
+
+After 20+ years of Debian everywhere, I switched to NixOS on my desktop 5 weeks ago.
+
+I'd like to keep using Propellor for that NixOS machine as well as my Debian fleet.
+
+Before I started trying to hack in support for NixOS, I thought I'd run a sanity check up the flag pole: is hacking in NixOS something I will actually need to do? (or does \"Unixlike\" cover most of my scenarios?)
+"""]]

`vidir` should be able to copy files as well
diff --git a/code/moreutils/discussion.mdwn b/code/moreutils/discussion.mdwn
index d54ca26b..d05982cc 100644
--- a/code/moreutils/discussion.mdwn
+++ b/code/moreutils/discussion.mdwn
@@ -289,8 +289,13 @@ Another improvement would be the addition would be to add checkboxes to control
 >> (although I'm not particularly interested in this, I only use git and tig is an
 >> excellent command-line utility to manage the repository). --G. Bilotta
 
+---
+
 How about adding copying ability to vidir?
 Items are recognized by the leading number in a line, right? A second instance of the same number should imply copying.
+> I tried using `vidir` like that today as I thought it had this feature already, but it doesn’t. Something like `%s/\(.*\)one\(.*\)/&\r\1two\2` (in `vim`) should copy every file containing “one” and replace it with “two” in the copy. That’s not too hard to add as a feature, or is it? -- K. Stephan
+
+---
 
 vidir is great, but when editing and deciding to abandon the sesssion,
 deleting the entire buffer should abort (like git commit messages) instead of

Added a comment: Can't really blame GitHub?
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_13_9b9caf8ab0be162f761e958a3452f4fb._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_13_9b9caf8ab0be162f761e958a3452f4fb._comment
new file mode 100644
index 00000000..252bc143
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_13_9b9caf8ab0be162f761e958a3452f4fb._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://milki.include-once.org/"
+ nickname="Mario"
+ avatar="http://cdn.libravatar.org/avatar/697b7e012d3908ba50728345a55969aa66635185ee363c20e5be90b54e6c5e9f"
+ subject="Can't really blame GitHub?"
+ date="2018-06-08T02:08:45Z"
+ content="""
+They both popularized and exploited a few design flaws of git. Rushing all eggs into another centralized basket is not really the lesson to be learned here.
+
+Git is not the only DVCS. It's just the one clinging to repositories-are-fileshrubbery thing. Nobody HAS TO make do with it merely because it's popular (again, GitHubs fault). Decentralization buys you nothing with an implied monoculture.
+"""]]

update link
diff --git a/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn b/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn
index 0cc02340..fc20c5af 100644
--- a/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn
+++ b/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn
@@ -38,7 +38,7 @@ used for something else (and to partly tackle the problem of using
 real-world time events when the underlying FRP library uses its own
 notion of time).
 
-[The code for my fridge](https://git.joeyh.name/index.cgi/joey/homepower.git/tree/reactive.hs#n72) 
+[The code for my fridge](https://git.joeyh.name/index.cgi/joey/homepower.git/tree/src/Automation/Fridge.hs) 
 is a work in progress since the fridge has not arrived yet, and because
 the question of in which situations an offgrid fridge should optimally 
 run and not run is really rather complicated.

response
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_12_11b5adc692c6d69b9596d3165fd5613d._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_12_11b5adc692c6d69b9596d3165fd5613d._comment
new file mode 100644
index 00000000..e4a49940
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_12_11b5adc692c6d69b9596d3165fd5613d._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""rate limit"""
+ date="2018-06-07T19:03:24Z"
+ content="""
+ Checking each issue for new comments takes an API call. The API is paginated == more API calls the more issues and comments there are. Finding comments attached to commits is additional API calls (and there was not a way to discover them other than trying every commit in turn last I checked). Repositories can have forks, which can have issues, which can have comments, for piles more API calls. (I know about this in some detail because I've written software to deal with all of it. It's constantly rate limited.)
+
+And then, most developers are not involved with a single software project. It's not uncommon to have dozens of dependencies you want to keep an eye on or are tangentially involved with in your work on a single project. Out of all your other projects.
+
+12 hours to check something out is not fertile ground for a distributed ecosystem to develop: As evidence see the lack of such an ecosystem.
+"""]]

Added a comment: Man management-level folks are older...
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_11_2e58412a6dde814e36d6acb786f35bc5._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_11_2e58412a6dde814e36d6acb786f35bc5._comment
new file mode 100644
index 00000000..baa733df
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_11_2e58412a6dde814e36d6acb786f35bc5._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="jason@84909c980a155d150ac3c9b2063e6248ee136634"
+ nickname="jason"
+ avatar="http://cdn.libravatar.org/avatar/445e077e0b53b5b104c2bfc969792a17"
+ subject="Man management-level folks are older..."
+ date="2018-06-07T13:11:55Z"
+ content="""
+I wonder how many closed-source companies using github have managers that remember \"DOS ain't done 'till Lotus don't run\" and are regretting making their family jewels available to MS.  And someone else being payed for it.
+
+I haven't seen the closed-source, private repo contracts, so they might have appropriate protections.
+"""]]

Added a comment: SIT
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_10_89ab048df6679b32af3cd412a00b89f2._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_10_89ab048df6679b32af3cd412a00b89f2._comment
new file mode 100644
index 00000000..77a07327
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_10_89ab048df6679b32af3cd412a00b89f2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="yrashk"
+ avatar="http://cdn.libravatar.org/avatar/ae2b294e24fd2e472bfca45ab19050c5"
+ subject="SIT"
+ date="2018-06-06T20:54:30Z"
+ content="""
+I wholeheartedly agree on the vendor lock-in with issues and pull requests. I've had a feeling that GitHub sort of well-intendedly hijacked open source communities. A few months ago, that pushed me to develop a resilient, future-proof, decentralized issue tracker that I later generalized for other problems as well ([SIT](https://sit.fyi)). I wrote a bit about my vision when I first announced it: [“Under the Covers of Code”](https://hackernoon.com/under-the-covers-of-code-3c4761fe965a)
+
+I really wanted to build something as future-proof and resilient as I can imagine, so SIT ended up not being specific to Git or any other SCM but instead relies on simple additive sets of files.
+"""]]

removed
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_7_0d1756dc1dc4bacc18be8d494b019ce9._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_7_0d1756dc1dc4bacc18be8d494b019ce9._comment
deleted file mode 100644
index d7611c3c..00000000
--- a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_7_0d1756dc1dc4bacc18be8d494b019ce9._comment
+++ /dev/null
@@ -1,10 +0,0 @@
-[[!comment format=mdwn
- username="yrashk"
- avatar="http://cdn.libravatar.org/avatar/ae2b294e24fd2e472bfca45ab19050c5"
- subject="comment 7"
- date="2018-06-06T19:36:34Z"
- content="""
-I wholeheartedly agree on the vendor lock-in with issues and pull requests. I've had a feeling that GitHub sort of well-intentedly hijacked open source communities. A few months ago, that pushed me to develop a resilient, future-proof, decentralized issue tracker that I later federalized for other problems as well ([SIT](https://sit.fyi)). I wrote a bit about my vision when I first announced it: [“Under the Covers of Code”](https://hackernoon.com/under-the-covers-of-code-3c4761fe965a). I wanted to build something really future-proof so I didn't opt to make it just git-based, but rather file-based and merge-conflict-free so it can be used with any SCM (or even without one)
-
-Maybe you'll find it useful.
-"""]]

Added a comment
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_10_36cc922c4ee94bbd42acd9141af93f2b._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_10_36cc922c4ee94bbd42acd9141af93f2b._comment
new file mode 100644
index 00000000..f1797f0d
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_10_36cc922c4ee94bbd42acd9141af93f2b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="gramplestramp"
+ avatar="http://cdn.libravatar.org/avatar/9867d203519e089dc247072a4c8ab730"
+ subject="comment 10"
+ date="2018-06-06T20:00:16Z"
+ content="""
+The API rate limit is 5000 requests per hour. If that's a barrier to you extracting your project data, then you're clearly doing something wrong.
+
+Also, the word you're looking for is \"criterion\". Be more precise in your vocabulary!
+"""]]

removed
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_11_5623dc7ba19a13e412bd0aa85cc960d1._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_11_5623dc7ba19a13e412bd0aa85cc960d1._comment
deleted file mode 100644
index 2c4d1bf7..00000000
--- a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_11_5623dc7ba19a13e412bd0aa85cc960d1._comment
+++ /dev/null
@@ -1,14 +0,0 @@
-[[!comment format=mdwn
- username="joeyh.name-20180606@c06bf6e0535bd537459660ee51f038ff70082861"
- nickname="joeyh.name-20180606"
- avatar="http://cdn.libravatar.org/avatar/838f7b4df8043e9a45ba50f9a178beab"
- subject="gists and wikis"
- date="2018-06-06T19:49:25Z"
- content="""
-> Consider all the data that's used to provide the value-added features on top of git. Issue tracking, wikis, notes in commits, lists of forks, pull requests, access controls, hooks, other configuration, etc.
-> Is that data stored in a git repository?
->
-> Github avoids doing that 
-
-Not quite true. Both gists and wiki pages are backed by git.
-"""]]

removed
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_10_fe8fae6de275b86ad2f72da5e8f804f6._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_10_fe8fae6de275b86ad2f72da5e8f804f6._comment
deleted file mode 100644
index 81e5adc1..00000000
--- a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_10_fe8fae6de275b86ad2f72da5e8f804f6._comment
+++ /dev/null
@@ -1,14 +0,0 @@
-[[!comment format=mdwn
- username="joeyh.name-20180606@c06bf6e0535bd537459660ee51f038ff70082861"
- nickname="joeyh.name-20180606"
- avatar="http://cdn.libravatar.org/avatar/838f7b4df8043e9a45ba50f9a178beab"
- subject="gists and wikis"
- date="2018-06-06T19:49:18Z"
- content="""
-> Consider all the data that's used to provide the value-added features on top of git. Issue tracking, wikis, notes in commits, lists of forks, pull requests, access controls, hooks, other configuration, etc.
-> Is that data stored in a git repository?
->
-> Github avoids doing that 
-
-Not quite true. Both gists and wiki pages are backed by git.
-"""]]

Added a comment: gists and wikis
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_11_5623dc7ba19a13e412bd0aa85cc960d1._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_11_5623dc7ba19a13e412bd0aa85cc960d1._comment
new file mode 100644
index 00000000..2c4d1bf7
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_11_5623dc7ba19a13e412bd0aa85cc960d1._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="joeyh.name-20180606@c06bf6e0535bd537459660ee51f038ff70082861"
+ nickname="joeyh.name-20180606"
+ avatar="http://cdn.libravatar.org/avatar/838f7b4df8043e9a45ba50f9a178beab"
+ subject="gists and wikis"
+ date="2018-06-06T19:49:25Z"
+ content="""
+> Consider all the data that's used to provide the value-added features on top of git. Issue tracking, wikis, notes in commits, lists of forks, pull requests, access controls, hooks, other configuration, etc.
+> Is that data stored in a git repository?
+>
+> Github avoids doing that 
+
+Not quite true. Both gists and wiki pages are backed by git.
+"""]]

Added a comment: gists and wikis
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_10_fe8fae6de275b86ad2f72da5e8f804f6._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_10_fe8fae6de275b86ad2f72da5e8f804f6._comment
new file mode 100644
index 00000000..81e5adc1
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_10_fe8fae6de275b86ad2f72da5e8f804f6._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="joeyh.name-20180606@c06bf6e0535bd537459660ee51f038ff70082861"
+ nickname="joeyh.name-20180606"
+ avatar="http://cdn.libravatar.org/avatar/838f7b4df8043e9a45ba50f9a178beab"
+ subject="gists and wikis"
+ date="2018-06-06T19:49:18Z"
+ content="""
+> Consider all the data that's used to provide the value-added features on top of git. Issue tracking, wikis, notes in commits, lists of forks, pull requests, access controls, hooks, other configuration, etc.
+> Is that data stored in a git repository?
+>
+> Github avoids doing that 
+
+Not quite true. Both gists and wiki pages are backed by git.
+"""]]

Added a comment: gists and wikis
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_9_723355b3f8c2592230f474d19b5533ed._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_9_723355b3f8c2592230f474d19b5533ed._comment
new file mode 100644
index 00000000..65f571db
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_9_723355b3f8c2592230f474d19b5533ed._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="joeyh.name-20180606@c06bf6e0535bd537459660ee51f038ff70082861"
+ nickname="joeyh.name-20180606"
+ avatar="http://cdn.libravatar.org/avatar/838f7b4df8043e9a45ba50f9a178beab"
+ subject="gists and wikis"
+ date="2018-06-06T19:49:03Z"
+ content="""
+> Consider all the data that's used to provide the value-added features on top of git. Issue tracking, wikis, notes in commits, lists of forks, pull requests, access controls, hooks, other configuration, etc.
+> Is that data stored in a git repository?
+>
+> Github avoids doing that 
+
+Not quite true. Both gists and wiki pages are backed by git.
+"""]]

Added a comment: Pagure as a replacement for GitHub
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_8_dce62f1de299f02120160e08bc4d4661._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_8_dce62f1de299f02120160e08bc4d4661._comment
new file mode 100644
index 00000000..c06f1e6f
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_8_dce62f1de299f02120160e08bc4d4661._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://ngompa.id.fedoraproject.org/"
+ nickname="ngompa"
+ avatar="http://cdn.libravatar.org/avatar/af8a9293484ed04b89081d848929b19a"
+ subject="Pagure as a replacement for GitHub"
+ date="2018-06-06T19:45:10Z"
+ content="""
+> Consider all the data that's used to provide the value-added features on top of git. Issue tracking, wikis, notes in commits, lists of forks, pull requests, access controls, hooks, other configuration, etc.
+> **Is that data stored in a git repository?**
+
+Fedora's [Pagure](https://pagure.io/pagure) mostly satisfies this requirement. All issues, comments, PR metadata, etc. are stored as Git repositories internally. You can pull, commit, and push through it that way. It also supports \"remote pull requests\" where the git repository of the source branch isn't hosted on the same server as the repo being targeted. The source repo doesn't even have to run Pagure!
+
+It uses Gitolite underneath to manage ACLs, and that isn't managed through Git repos, but instead through the application with settings in the database. But I'd argue all the meaningful information is available in a useful form.
+"""]]

Added a comment
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_7_0d1756dc1dc4bacc18be8d494b019ce9._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_7_0d1756dc1dc4bacc18be8d494b019ce9._comment
new file mode 100644
index 00000000..d7611c3c
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_7_0d1756dc1dc4bacc18be8d494b019ce9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="yrashk"
+ avatar="http://cdn.libravatar.org/avatar/ae2b294e24fd2e472bfca45ab19050c5"
+ subject="comment 7"
+ date="2018-06-06T19:36:34Z"
+ content="""
+I wholeheartedly agree on the vendor lock-in with issues and pull requests. I've had a feeling that GitHub sort of well-intentedly hijacked open source communities. A few months ago, that pushed me to develop a resilient, future-proof, decentralized issue tracker that I later federalized for other problems as well ([SIT](https://sit.fyi)). I wrote a bit about my vision when I first announced it: [“Under the Covers of Code”](https://hackernoon.com/under-the-covers-of-code-3c4761fe965a). I wanted to build something really future-proof so I didn't opt to make it just git-based, but rather file-based and merge-conflict-free so it can be used with any SCM (or even without one)
+
+Maybe you'll find it useful.
+"""]]

Added a comment: git-dit
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_6_3a87a89f1b4f243bc2bbff95a058f43a._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_6_3a87a89f1b4f243bc2bbff95a058f43a._comment
new file mode 100644
index 00000000..0428573e
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_6_3a87a89f1b4f243bc2bbff95a058f43a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="girst"
+ avatar="http://cdn.libravatar.org/avatar/109c4908433659b8675806b7ba06d980"
+ subject="git-dit"
+ date="2018-06-06T19:19:59Z"
+ content="""
+There is some effort to get issues into the repository itself: https://github.com/neithernut/git-dit
+
+
+"""]]

username
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_3_2b686b0c4167535126dae9a60be89503._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_3_2b686b0c4167535126dae9a60be89503._comment
index 06a83aa3..99cd0b66 100644
--- a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_3_2b686b0c4167535126dae9a60be89503._comment
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_3_2b686b0c4167535126dae9a60be89503._comment
@@ -1,5 +1,5 @@
 [[!comment format=mdwn
- username="joeyh@52ab0fe1b447869e9a584778dae52170a7f5a3a6"
+ username="colbyrussell"
  nickname="colbyrussell"
  avatar="http://cdn.libravatar.org/avatar/2d590c8209c6af9b181dcd151a639c1f"
  subject="Git repos and abstraction level"
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_4_1f56947aac0f997fe1bb24acd15a8217._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_4_1f56947aac0f997fe1bb24acd15a8217._comment
index 791e84bb..8392c090 100644
--- a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_4_1f56947aac0f997fe1bb24acd15a8217._comment
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_4_1f56947aac0f997fe1bb24acd15a8217._comment
@@ -1,5 +1,5 @@
 [[!comment format=mdwn
- username="joeyh@52ab0fe1b447869e9a584778dae52170a7f5a3a6"
+ username="colbyrussell"
  nickname="colbyrussell"
  avatar="http://cdn.libravatar.org/avatar/2d590c8209c6af9b181dcd151a639c1f"
  subject="comment 4"

response
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_3_2b686b0c4167535126dae9a60be89503._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_3_2b686b0c4167535126dae9a60be89503._comment
index 0e6ac226..06a83aa3 100644
--- a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_3_2b686b0c4167535126dae9a60be89503._comment
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_3_2b686b0c4167535126dae9a60be89503._comment
@@ -1,6 +1,6 @@
 [[!comment format=mdwn
  username="joeyh@52ab0fe1b447869e9a584778dae52170a7f5a3a6"
- nickname="joeyh"
+ nickname="colbyrussell"
  avatar="http://cdn.libravatar.org/avatar/2d590c8209c6af9b181dcd151a639c1f"
  subject="Git repos and abstraction level"
  date="2018-06-06T18:13:15Z"
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_4_1f56947aac0f997fe1bb24acd15a8217._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_4_1f56947aac0f997fe1bb24acd15a8217._comment
index 58f251bf..791e84bb 100644
--- a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_4_1f56947aac0f997fe1bb24acd15a8217._comment
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_4_1f56947aac0f997fe1bb24acd15a8217._comment
@@ -1,6 +1,6 @@
 [[!comment format=mdwn
  username="joeyh@52ab0fe1b447869e9a584778dae52170a7f5a3a6"
- nickname="joeyh"
+ nickname="colbyrussell"
  avatar="http://cdn.libravatar.org/avatar/2d590c8209c6af9b181dcd151a639c1f"
  subject="comment 4"
  date="2018-06-06T18:17:23Z"
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_5_2389223ef35c20ee06996c54c7a8d5ec._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_5_2389223ef35c20ee06996c54c7a8d5ec._comment
new file mode 100644
index 00000000..61cdd80d
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_5_2389223ef35c20ee06996c54c7a8d5ec._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 5"""
+ date="2018-06-06T18:22:43Z"
+ content="""
+@colbyrussell, my guess is you logged in by email with
+joeyh@yourdomain.com. I've adjusted the nickname displayed.
+
+To your point: I have done a fair bit of exploration of what makes sense to
+shoehorn into git and how to do it, and issues and PRs and project
+configuration data are really pretty trivial to do. And it's been done,
+many times before -- <https://dist-bugs.branchable.com/> -- but
+<https://xkcd.com/927/> applies to those efforts. So I'm not suggesting
+this from a naive position.
+
+And while your logic is impeccible, so is the relentless logic of VC backed
+startups and how they develop. No criteria are perfect (see above footnote), 
+but I do feel this is a good one, and better in this case than 
+"is it free software?" for pointing in the direction of some solutions.
+(Combine the two criteria and you get the 
+[Franklin Street Statement](http://wiki.p2pfoundation.net/Franklin_Street_Statement_on_Freedom_and_Network_Services)..)
+"""]]

Added a comment
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_4_1f56947aac0f997fe1bb24acd15a8217._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_4_1f56947aac0f997fe1bb24acd15a8217._comment
new file mode 100644
index 00000000..58f251bf
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_4_1f56947aac0f997fe1bb24acd15a8217._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="joeyh@52ab0fe1b447869e9a584778dae52170a7f5a3a6"
+ nickname="joeyh"
+ avatar="http://cdn.libravatar.org/avatar/2d590c8209c6af9b181dcd151a639c1f"
+ subject="comment 4"
+ date="2018-06-06T18:17:23Z"
+ content="""
+I don't know why that comment is showing up as coming from \"joeyh\"; that's actually me (@colbyrussell.com), and I didn't select any option to attribute it to \"joeyh\" (or in any other way, for that matter).
+"""]]

Added a comment: Git repos and abstraction level
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_3_2b686b0c4167535126dae9a60be89503._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_3_2b686b0c4167535126dae9a60be89503._comment
new file mode 100644
index 00000000..0e6ac226
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_3_2b686b0c4167535126dae9a60be89503._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="joeyh@52ab0fe1b447869e9a584778dae52170a7f5a3a6"
+ nickname="joeyh"
+ avatar="http://cdn.libravatar.org/avatar/2d590c8209c6af9b181dcd151a639c1f"
+ subject="Git repos and abstraction level"
+ date="2018-06-06T18:13:15Z"
+ content="""
+That first paragraph is a killer opener, like a song that's ridiculously good by how brutal it manages to be because of the way every line packs a punch.
+
+Having said that, it doesn't follow that because GitHub made deliberate choices for anticompetitive lock-in, then another solution—say, a P2P one—should therefore store projects' \"extras\" in Git repos.
+
+In other words:
+
+*If $PARTY had chosen Git for $USECASE, it wouldn't have let them achieve lock-in*, does not mean, *project extras stored in something besides Git necessarily results in lock-in*.  It's possible that Git repos are the entirely wrong abstraction for this.  Indeed, insisting on stuffing all the auxiliary stuff into Git, too, (and all the implications of choosing those constraints) strongly smells of that phenomenon where people pick up one abstraction and then try to shoehorn it in everywhere else, regardless of whether it's well-suited for that use case or not.  I write this even knowing your affinity and relationship to Git with git-annex & co.
+"""]]

comment
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_2_20dc6365bc57456c7b44aa368e2f9819._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_2_20dc6365bc57456c7b44aa368e2f9819._comment
new file mode 100644
index 00000000..b125dbe2
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_2_20dc6365bc57456c7b44aa368e2f9819._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2018-06-06T17:49:53Z"
+ content="""
+And data is the plural of datum. Except in common usage neither is.
+
+And this kind of pedantry feels like a tactic. 
+
+Oh, and your comment was committed to git, so at least it demonstrated
+something useful.
+"""]]

Correct a spelling mistake.
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn b/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn
index cc651ff3..7dd36d5d 100644
--- a/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn
@@ -1,4 +1,4 @@
-I could write a lot of things about the Github aquisition by Microsoft.
+I could write a lot of things about the Github acquisition by Microsoft.
 About Github's embrace and extend of git, and how it passed unnoticed by
 people who now fear the same thing now that Microsoft is in the
 picture. About the stultifying effects of Github's centralization, and

Added a comment: Criteria
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_1_0d77a12534da43028d5eacdc3b25a660._comment b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_1_0d77a12534da43028d5eacdc3b25a660._comment
new file mode 100644
index 00000000..3b3d87be
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github/comment_1_0d77a12534da43028d5eacdc3b25a660._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="moses.skoda@5596bce29110454b6f2f526c9ebd0c6b123bee49"
+ nickname="moses.skoda"
+ avatar="http://cdn.libravatar.org/avatar/df1440e57234792f07c901384e07ef6b"
+ subject="Criteria"
+ date="2018-06-06T17:28:30Z"
+ content="""
+Hi, just an FYI that I thought might be appreciated: *criteria* is a plural form of the word *criterion*
+"""]]

clarify
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn b/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn
index e759e763..cc651ff3 100644
--- a/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn
@@ -35,5 +35,5 @@ an opportunity to get us out of the trap we now find ourselves in.
 
 [1] Although in the case of a P2P system which uses a distributed data
 structure, that can have many of the same benefits as using git. 
-So I'd give git-ssb, which stores issues etc as ssb messages, a pass
-on this, for example.
+So, git-ssb, which stores issues etc as ssb messages, is just as good,
+for example.

fix link
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn b/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn
index 776ab030..e759e763 100644
--- a/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn
@@ -14,7 +14,7 @@ top of git. Issue tracking, wikis, notes in commits, lists of forks, pull
 requests, access controls, hooks, other configuration, etc.  
 **Is that data stored in a git repository?**
 
-Github [avoids doing that](a_Github_survey) and there's a good
+Github [[avoids doing that|a_Github_survey]] and there's a good
 reason why: By keeping this data in their own database, they lock you into
 the service. Consider if Github issues had been stored in a git repository
 next to the code. Anyone could quickly and easily clone the issue data,

blog update
diff --git a/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn b/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn
new file mode 100644
index 00000000..776ab030
--- /dev/null
+++ b/blog/entry/the_single_most_important_criteria_when_replacing_Github.mdwn
@@ -0,0 +1,39 @@
+I could write a lot of things about the Github aquisition by Microsoft.
+About Github's embrace and extend of git, and how it passed unnoticed by
+people who now fear the same thing now that Microsoft is in the
+picture. About the stultifying effects of Github's centralization, and
+its retardant effect on general innovation in spaces around git and
+software development infrastructure.
+
+Instead I'd rather highlight one simple criteria you can consider when
+you are evaluating any git hosting service, whether it's Gitlab or
+something self-hosted, or federated, or P2P[1], or whatever:
+
+Consider all the data that's used to provide the value-added features on
+top of git. Issue tracking, wikis, notes in commits, lists of forks, pull
+requests, access controls, hooks, other configuration, etc.  
+**Is that data stored in a git repository?**
+
+Github [avoids doing that](a_Github_survey) and there's a good
+reason why: By keeping this data in their own database, they lock you into
+the service. Consider if Github issues had been stored in a git repository
+next to the code. Anyone could quickly and easily clone the issue data,
+consume it, write alternative issue tracking interfaces, which then start
+accepting git pushes of issue updates and syncing all around. That would have
+quickly became *the* de-facto distributed issue tracking data format.
+
+Instead, Github stuck it in a database, with a rate-limited API, and while
+this probably had as much to do with expediency, and a certain centralized
+mindset, as intentional lock-in at first, it's now become such good lock-in
+that Microsoft felt Github was worth $7 billion.
+
+So, if whatever thing you're looking at instead of Github doesn't do
+this, it's at worst hoping to emulate that, or at best it's neglecting
+an opportunity to get us out of the trap we now find ourselves in.
+
+----
+
+[1] Although in the case of a P2P system which uses a distributed data
+structure, that can have many of the same benefits as using git. 
+So I'd give git-ssb, which stores issues etc as ssb messages, a pass
+on this, for example.

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 ca8b8fad..9a6c362d 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 48 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 49 "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 d80f87e9..ca8b8fad 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 47 "watched it all, liked it" 9 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 48 "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 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 44c6141b..d80f87e9 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 47 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 13 "not interested"]]
+[[!poll 47 "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: solar thermal refridgerators
diff --git a/blog/entry/fridge_0.1/comment_3_f3207590c8c6589c85a0e33c1841d928._comment b/blog/entry/fridge_0.1/comment_3_f3207590c8c6589c85a0e33c1841d928._comment
new file mode 100644
index 00000000..5967bd2f
--- /dev/null
+++ b/blog/entry/fridge_0.1/comment_3_f3207590c8c6589c85a0e33c1841d928._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~markvdb"
+ nickname="markvdb"
+ avatar="http://cdn.libravatar.org/avatar/fb7b18b417b7accd1d52371b84cd4372a919bdad7b14e931c007ffb5d2864065"
+ subject="solar thermal refridgerators"
+ date="2018-05-21T09:19:31Z"
+ content="""
+An interesting experiment might be to convert your old propane fridge to use solar thermal as its heat source. There's several open hardware experiments in the solar thermal space. Same thing for solar refridgeration.
+"""]]

fix my numbers
diff --git a/blog/entry/fridge_0.1/comment_2_595a56e187cf511dccdc318d99ec1228._comment b/blog/entry/fridge_0.1/comment_2_595a56e187cf511dccdc318d99ec1228._comment
index 0c8810d0..2c63028d 100644
--- a/blog/entry/fridge_0.1/comment_2_595a56e187cf511dccdc318d99ec1228._comment
+++ b/blog/entry/fridge_0.1/comment_2_595a56e187cf511dccdc318d99ec1228._comment
@@ -4,12 +4,12 @@
  date="2018-05-19T15:23:49Z"
  content="""
 12v fridges are also much more expensive than regular consumer goods,
-the premium is often 300%.
+the premium is often 400%.
 
 They may be a little more efficient due to better insulation. They don't
 seem to use any less watts when running.
 
-You can buy a lot of solar panels for the $600 I saved on going with a
+You can buy a lot of solar panels for the $900 I saved on going with a
 regular chest freezer. Almost as many solar panels as I am using to power
 it..
 """]]

respinse
diff --git a/blog/entry/fridge_0.1/comment_2_595a56e187cf511dccdc318d99ec1228._comment b/blog/entry/fridge_0.1/comment_2_595a56e187cf511dccdc318d99ec1228._comment
new file mode 100644
index 00000000..0c8810d0
--- /dev/null
+++ b/blog/entry/fridge_0.1/comment_2_595a56e187cf511dccdc318d99ec1228._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2018-05-19T15:23:49Z"
+ content="""
+12v fridges are also much more expensive than regular consumer goods,
+the premium is often 300%.
+
+They may be a little more efficient due to better insulation. They don't
+seem to use any less watts when running.
+
+You can buy a lot of solar panels for the $600 I saved on going with a
+regular chest freezer. Almost as many solar panels as I am using to power
+it..
+"""]]
diff --git a/blog/entry/my_haskell_controlled_offgrid_fridge/comment_1_3774973c089b47a2e53b2a3193d9e66e._comment b/blog/entry/my_haskell_controlled_offgrid_fridge/comment_1_3774973c089b47a2e53b2a3193d9e66e._comment
deleted file mode 100644
index e3f41978..00000000
--- a/blog/entry/my_haskell_controlled_offgrid_fridge/comment_1_3774973c089b47a2e53b2a3193d9e66e._comment
+++ /dev/null
@@ -1,8 +0,0 @@
-[[!comment format=mdwn
- username="Hello1992"
- avatar="http://cdn.libravatar.org/avatar/fa07ec46f84f47023bfc79d220d2f535"
- subject="Hello"
- date="2018-05-19T10:05:16Z"
- content="""
-I cum to Haskall every night, because Bjarne forces me to use a strap on. I'm a little rusty, but Ritchie said everything is going to be ok.
-"""]]

Added a comment: Fridges
diff --git a/blog/entry/fridge_0.1/comment_1_6605db89817c694041d2f13863b9c442._comment b/blog/entry/fridge_0.1/comment_1_6605db89817c694041d2f13863b9c442._comment
new file mode 100644
index 00000000..ac8a752c
--- /dev/null
+++ b/blog/entry/fridge_0.1/comment_1_6605db89817c694041d2f13863b9c442._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="regimbal.grant@92c5ff8276af4860a9d99e187752261329203361"
+ nickname="regimbal.grant"
+ avatar="http://cdn.libravatar.org/avatar/f83dfcb9d5ff90e1e881595b8c3b13b0"
+ subject="Fridges"
+ date="2018-05-19T15:09:04Z"
+ content="""
+You should look into some of the fridges used on expeditions. They are much more efficient than regular fridges and run on 12 volt systems. http://store.arbusa.com/ARB-Fridge-Freezer-50-Qt-10800472-P3626.aspx
+"""]]

Added a comment: Hello
diff --git a/blog/entry/my_haskell_controlled_offgrid_fridge/comment_1_3774973c089b47a2e53b2a3193d9e66e._comment b/blog/entry/my_haskell_controlled_offgrid_fridge/comment_1_3774973c089b47a2e53b2a3193d9e66e._comment
new file mode 100644
index 00000000..e3f41978
--- /dev/null
+++ b/blog/entry/my_haskell_controlled_offgrid_fridge/comment_1_3774973c089b47a2e53b2a3193d9e66e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Hello1992"
+ avatar="http://cdn.libravatar.org/avatar/fa07ec46f84f47023bfc79d220d2f535"
+ subject="Hello"
+ date="2018-05-19T10:05:16Z"
+ content="""
+I cum to Haskall every night, because Bjarne forces me to use a strap on. I'm a little rusty, but Ritchie said everything is going to be ok.
+"""]]

recrop
diff --git a/blog/pics/fridgecooldown.png b/blog/pics/fridgecooldown.png
index 7e98ac32..320a68e7 100644
Binary files a/blog/pics/fridgecooldown.png and b/blog/pics/fridgecooldown.png differ

blog update
diff --git a/blog/entry/fridge_0.1.mdwn b/blog/entry/fridge_0.1.mdwn
new file mode 100644
index 00000000..cbadaea0
--- /dev/null
+++ b/blog/entry/fridge_0.1.mdwn
@@ -0,0 +1,41 @@
+Imagine something really cool, like a fridge connected to a powerwall,
+powered entirely by solar panels. What could be cooler than that?
+
+How about a fridge powered entirely by solar panels without the powerwall?
+Zero battery use, and yet it still preserves your food.
+
+That's much cooler, because batteries, even hyped ones like the powerwall,
+are expensive and innefficient and have limited cycles. Solar panels are
+cheap and efficient now. With enough solar panels that the fridge has
+power to cool down most days (even cloudy days), and a smart enough
+control system, the fridge itself becomes the battery -- a cold battery.
+
+I'm live coding my fridge, with that goal in mind.
+You can follow along in
+[this design thread on secure scuttlebutt](https://viewer.scuttlebot.io/%25Pg7%2BlVNJS13o2GBftbMLC2V0BgB3PSeX1L3cVdnUifc%3D.sha256),
+and [my git commits](https://git.joeyh.name/index.cgi/joey/homepower.git/log/),
+and you can watch
+[real-time data from my fridge](http://homepower.joeyh.name/fridge.html).
+
+Over the past two days, which were not especially sunny, my 1 kilowatt of
+solar panels has managed to cool the fridge down close to standard fridge
+temperatures. The temperature remains steady overnight thanks to added
+thermal mass in the fridge. My food seems safe in it, despite it being
+powered off for 14 hours each night.
+
+[[!img pics/fridgecooldown.png alt="graph of fridge temperature, starting at 13C and trending downwards to 5C over 24 hours"]]
+
+(Numbers in this graph are running higher than the actual temps of food in
+the fridge, for reasons explained in the scuttlebutt thread.)
+
+Of course, the longterm viability of a fridge that never draws from a
+battery is TBD; I'll know within a year if it works for me.
+
+[[!img pics/bananafridge.jpg alt="bunch of bananas resting on top of chest freezer fridge conversion"]]
+
+I've written about the coding side of this project before,
+in [[my_haskell_controlled_offgrid_fridge]]. The reactive-banana-automation 
+library is working well in this application. My 
+[[AIMS inverter control board|AIMS_inverter_control_via_GPIO_ports]]
+and [[easy-peasy-devicetree-squeezy]] were other groundwork for
+this project.
diff --git a/blog/pics/fridgecooldown.png b/blog/pics/fridgecooldown.png
new file mode 100644
index 00000000..7e98ac32
Binary files /dev/null and b/blog/pics/fridgecooldown.png differ

pic
diff --git a/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn b/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn
index e3dbaee6..0cc02340 100644
--- a/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn
+++ b/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn
@@ -77,3 +77,4 @@ BTW, building a 400 line library and writing reams of control code for a
 fridge that has not been installed yet is what we Haskell programmers call
 "laziness".
 
+[[!img pics/bananafridge.jpg]]
diff --git a/blog/pics/bananafridge.jpg b/blog/pics/bananafridge.jpg
new file mode 100644
index 00000000..e8b62c07
Binary files /dev/null and b/blog/pics/bananafridge.jpg differ

add news item for pdmenu 1.3.5
diff --git a/code/pdmenu/news/version_1.3.0.mdwn b/code/pdmenu/news/version_1.3.0.mdwn
deleted file mode 100644
index 33deee2a..00000000
--- a/code/pdmenu/news/version_1.3.0.mdwn
+++ /dev/null
@@ -1,6 +0,0 @@
-pdmenu 1.3.0 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Add support for "exec entries"; menu entries that pdmenu execs,
-     replacing itself with their process. Contributed by Stephen Blott
-   * Add -s switch enabling superhot mode, in which pressing an unambiguous
-     menu hotkey immediately runs that menu item. Contributed by Stephen Blott"""]]
\ No newline at end of file
diff --git a/code/pdmenu/news/version_1.3.5.mdwn b/code/pdmenu/news/version_1.3.5.mdwn
new file mode 100644
index 00000000..cc58e93f
--- /dev/null
+++ b/code/pdmenu/news/version_1.3.5.mdwn
@@ -0,0 +1,8 @@
+pdmenu 1.3.5 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Added --borderspace/-b option, which uses spaces rather than line
+     drawing characters around the menu. Mostly useful for screen readers,
+     also perhaps a more modern look.
+     Thanks to Storm Dragon for suggesting this feature.
+   * Added missing documentation for --superhot/-s to man page.
+   * Update my email address."""]]
\ No newline at end of file

format format
diff --git a/blog/entry/more_fun_with_reactive-banana-automation.mdwn b/blog/entry/more_fun_with_reactive-banana-automation.mdwn
index a5a7a4d3..d8d51377 100644
--- a/blog/entry/more_fun_with_reactive-banana-automation.mdwn
+++ b/blog/entry/more_fun_with_reactive-banana-automation.mdwn
@@ -8,17 +8,17 @@ using my [reactive-banana-automation](http://hackage.haskell.org/package/reactiv
 library is almost shorter than the English description, and certianly clearer.
 
 [[!format haskell """
-	inverterPowerChange :: Sensors t -> MomentAutomation (Behavior (Maybe PowerChange))
-	inverterPowerChange sensors = do
-	    lowpower <- lowpowerMode sensors
-	    fridgepowerchange <- fridgePowerChange sensors
-	    wifiusers <- numWifiUsers sensors
-	    return $ react <$> lowpower <*> fridgepowerchange <*> wifiusers
-	where
-	    react lowpower fridgepowerchange wifiusers
-	            | lowpower = Just PowerOff
-	            | wifiusers > 0 = Just PowerOn
-	            | otherwise = fridgepowerchange
+inverterPowerChange :: Sensors t -> MomentAutomation (Behavior (Maybe PowerChange))
+inverterPowerChange sensors = do
+    lowpower <- lowpowerMode sensors
+    fridgepowerchange <- fridgePowerChange sensors
+    wifiusers <- numWifiUsers sensors
+    return $ react <$> lowpower <*> fridgepowerchange <*> wifiusers
+where
+    react lowpower fridgepowerchange wifiusers
+            | lowpower = Just PowerOff
+            | wifiusers > 0 = Just PowerOn
+            | otherwise = fridgepowerchange
 """]]
 
 Of course, there are complexities under the hood, like where does
@@ -37,34 +37,32 @@ with this style of testing. For example, here's how it determines
 when the house needs to be in low power mode, including the tests:
 
 [[!format haskell """
-	-- | Start by assuming we're not in low power mode, to avoid
-	-- entering it before batteryVoltage is available.
-	--
-	-- If batteryVoltage continues to be unavailable, enter low power mode for
-	-- safety.
-	-- 
-	-- >>> runner <- observeAutomation (runInverterUnless lowpowerMode) (mkSensors (pure ()))
-	-- >>> runner $ \sensors -> gotEvent (dhcpClients sensors) []
-	-- []
-	-- >>> runner $ \sensors -> sensorUnavailable (batteryVoltage sensors)
-	-- [InverterPower PowerOff]
-	-- >>> runner $ \sensors -> batteryVoltage sensors =: Volts 25
-	-- [InverterPower PowerOn]
-	-- >>> runner $ \sensors -> batteryVoltage sensors =: Volts 20
-	-- [InverterPower PowerOff]
-	-- >>> runner $ \sensors -> batteryVoltage sensors =: Volts 25
-	-- [InverterPower PowerOn]
-	-- >>> runner $ \sensors -> sensorUnavailable (batteryVoltage sensors)
-	-- [InverterPower PowerOff]
-	lowpowerMode :: Sensors t -> MomentAutomation (Behavior Bool)
-	lowpowerMode sensors = automationStepper False
-		=<< fmap calc <$> getEventFrom (batteryVoltage sensors)
-	  where
-		-- Below 24.0 (really 23.5 or so) is danger zone for lead acid.
-		calc (Sensed v) = v < Volts 24.1
-		-- When battery  voltage is not known, default to low power
-		-- mode for safety.
-		calc SensorUnavailable = True
+-- | Start by assuming we're not in low power mode, to avoid
+-- entering it before batteryVoltage is available.
+--
+-- If batteryVoltage continues to be unavailable, enter low power mode for
+-- safety.
+-- 
+-- >>> runner <- observeAutomation (runInverterUnless lowpowerMode) (mkSensors (pure ()))
+-- >>> runner $ \sensors -> gotEvent (dhcpClients sensors) []
+-- []
+-- >>> runner $ \sensors -> sensorUnavailable (batteryVoltage sensors)
+-- [InverterPower PowerOff]
+-- >>> runner $ \sensors -> batteryVoltage sensors =: Volts 25
+-- [InverterPower PowerOn]
+-- >>> runner $ \sensors -> batteryVoltage sensors =: Volts 20
+-- [InverterPower PowerOff]
+-- >>> runner $ \sensors -> batteryVoltage sensors =: Volts 25
+-- [InverterPower PowerOn]
+-- >>> runner $ \sensors -> sensorUnavailable (batteryVoltage sensors)
+-- [InverterPower PowerOff]
+lowpowerMode :: Sensors t -> MomentAutomation (Behavior Bool)
+lowpowerMode sensors = automationStepper False
+	=<< fmap calc <$> getEventFrom (batteryVoltage sensors)
+  where
+	-- Below 24.0 (really 23.5 or so) is danger zone for lead acid.
+	calc (Sensed v) = v < Volts 24.1
+	calc SensorUnavailable = True
 """]]
 
 The sensor data is available over http, so I can run this controller

format format
diff --git a/blog/entry/more_fun_with_reactive-banana-automation.mdwn b/blog/entry/more_fun_with_reactive-banana-automation.mdwn
index c5209606..a5a7a4d3 100644
--- a/blog/entry/more_fun_with_reactive-banana-automation.mdwn
+++ b/blog/entry/more_fun_with_reactive-banana-automation.mdwn
@@ -36,7 +36,7 @@ the FRP code. I designed reactive-banana-automation to work well
 with this style of testing. For example, here's how it determines
 when the house needs to be in low power mode, including the tests:
 
-[[[!format haskell """
+[[!format haskell """
 	-- | Start by assuming we're not in low power mode, to avoid
 	-- entering it before batteryVoltage is available.
 	--

format format
diff --git a/blog/entry/more_fun_with_reactive-banana-automation.mdwn b/blog/entry/more_fun_with_reactive-banana-automation.mdwn
index cceddb7d..c5209606 100644
--- a/blog/entry/more_fun_with_reactive-banana-automation.mdwn
+++ b/blog/entry/more_fun_with_reactive-banana-automation.mdwn
@@ -36,7 +36,7 @@ the FRP code. I designed reactive-banana-automation to work well
 with this style of testing. For example, here's how it determines
 when the house needs to be in low power mode, including the tests:
 
-[[[format haskell """
+[[[!format haskell """
 	-- | Start by assuming we're not in low power mode, to avoid
 	-- entering it before batteryVoltage is available.
 	--

blog update
diff --git a/blog/entry/more_fun_with_reactive-banana-automation.mdwn b/blog/entry/more_fun_with_reactive-banana-automation.mdwn
new file mode 100644
index 00000000..cceddb7d
--- /dev/null
+++ b/blog/entry/more_fun_with_reactive-banana-automation.mdwn
@@ -0,0 +1,78 @@
+My house knows when people are using the wifi, and keeps the inverter on so
+that the satellite internet is powered up, unless the battery is too low.
+When nobody is using the wifi, the inverter turns off, except when it's
+needed to power the fridge.
+
+Sounds a little complicated, doesn't it? The code to automate that 
+using my [reactive-banana-automation](http://hackage.haskell.org/package/reactive-banana-automation)
+library is almost shorter than the English description, and certianly clearer.
+
+[[!format haskell """
+	inverterPowerChange :: Sensors t -> MomentAutomation (Behavior (Maybe PowerChange))
+	inverterPowerChange sensors = do
+	    lowpower <- lowpowerMode sensors
+	    fridgepowerchange <- fridgePowerChange sensors
+	    wifiusers <- numWifiUsers sensors
+	    return $ react <$> lowpower <*> fridgepowerchange <*> wifiusers
+	where
+	    react lowpower fridgepowerchange wifiusers
+	            | lowpower = Just PowerOff
+	            | wifiusers > 0 = Just PowerOn
+	            | otherwise = fridgepowerchange
+"""]]
+
+Of course, there are complexities under the hood, like where does
+`numWifiUsers` come from? (It uses inotify to detect changes to the
+DHCP leases file, and tracks when leases expire.) I'm up to 1200 lines of
+custom code for my house, only 170 lines of which are control code like
+the above. 
+
+But that code is the core, and it's where most of the bugs would be.
+The goal is to avoid most of the bugs by using FRP and Haskell
+the way I have, and the rest by testing.
+
+For testing, I'm using doctest to embed test cases along with
+the FRP code. I designed reactive-banana-automation to work well
+with this style of testing. For example, here's how it determines
+when the house needs to be in low power mode, including the tests:
+
+[[[format haskell """
+	-- | Start by assuming we're not in low power mode, to avoid
+	-- entering it before batteryVoltage is available.
+	--
+	-- If batteryVoltage continues to be unavailable, enter low power mode for
+	-- safety.
+	-- 
+	-- >>> runner <- observeAutomation (runInverterUnless lowpowerMode) (mkSensors (pure ()))
+	-- >>> runner $ \sensors -> gotEvent (dhcpClients sensors) []
+	-- []
+	-- >>> runner $ \sensors -> sensorUnavailable (batteryVoltage sensors)
+	-- [InverterPower PowerOff]
+	-- >>> runner $ \sensors -> batteryVoltage sensors =: Volts 25
+	-- [InverterPower PowerOn]
+	-- >>> runner $ \sensors -> batteryVoltage sensors =: Volts 20
+	-- [InverterPower PowerOff]
+	-- >>> runner $ \sensors -> batteryVoltage sensors =: Volts 25
+	-- [InverterPower PowerOn]
+	-- >>> runner $ \sensors -> sensorUnavailable (batteryVoltage sensors)
+	-- [InverterPower PowerOff]
+	lowpowerMode :: Sensors t -> MomentAutomation (Behavior Bool)
+	lowpowerMode sensors = automationStepper False
+		=<< fmap calc <$> getEventFrom (batteryVoltage sensors)
+	  where
+		-- Below 24.0 (really 23.5 or so) is danger zone for lead acid.
+		calc (Sensed v) = v < Volts 24.1
+		-- When battery  voltage is not known, default to low power
+		-- mode for safety.
+		calc SensorUnavailable = True
+"""]]
+
+The sensor data is available over http, so I can run this controller
+code in test mode, on my laptop, and observe how it reacts to
+real-world circumstances.
+
+	joey@darkstar:~/src/homepower>./controller test
+	InverterPower PowerOn
+	FridgeRelay PowerOff
+
+Previously: [[my haskell controlled offgrid fridge]]

add news item for scroll 1.20180421
diff --git a/code/scroll/news/version_1.20180421.mdwn b/code/scroll/news/version_1.20180421.mdwn
new file mode 100644
index 00000000..1efc75b1
--- /dev/null
+++ b/code/scroll/news/version_1.20180421.mdwn
@@ -0,0 +1,4 @@
+scroll 1.20180421 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Added stack.yaml.
+   * Fix build with ghc 8.2."""]]
\ No newline at end of file

add
diff --git a/code.mdwn b/code.mdwn
index 38a0f9ee..1e8dec56 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -17,8 +17,9 @@ The stuff that's swapped into my local cache at the moment.
 [[ikiwiki-hosting]]
 [[github-backup]]
 [[shell-monad]]
-[[scuttlebutt-types]]
+[[reactive-banana-automation]]
 [[easy-peasy-devicetree-squeezy]]
+[[scuttlebutt-types]]
 
 ## Less active projects
 
diff --git a/code/reactive-banana-automation.mdwn b/code/reactive-banana-automation.mdwn
new file mode 100644
index 00000000..0c1b7162
--- /dev/null
+++ b/code/reactive-banana-automation.mdwn
@@ -0,0 +1,3 @@
+Home automation using FRP
+
+<http://hackage.haskell.org/package/reactive-banana-automation>

layout
diff --git a/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn b/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn
index e4a15977..e3dbaee6 100644
--- a/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn
+++ b/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn
@@ -13,11 +13,11 @@ Of course, I want the control code to be as robust as possible, well
 tested, and easy to modify without making mistakes. Pure functional Haskell
 code.
 
+<img src="https://wiki.haskell.org/wikiupload/7/7c/Reactive-Banana-banana.png">
 There are many Haskell libraries for FRP, and I have not looked at most of
 them in any detail. I settled on
 [reactive-banana](https://wiki.haskell.org/Reactive-banana) because it
 has a good reputation and amazing testimonials. 
-<img src="https://wiki.haskell.org/wikiupload/7/7c/Reactive-Banana-banana.png">
 
 > "In the programming-language world, one rule of survival is simple:
 > dance or die. This library makes dancing easy." – Simon Banana Jones

blog update
diff --git a/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn b/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn
new file mode 100644
index 00000000..e4a15977
--- /dev/null
+++ b/blog/entry/my_haskell_controlled_offgrid_fridge.mdwn
@@ -0,0 +1,79 @@
+I'm preparing for a fridge upgrade, away from the tiny propane fridge to a
+chest freezer conversion. My home computer will be monitoring the
+fridge temperature and the state of my offgrid energy system, and turning the
+fridge on and off using a relay and the
+[[inverter control board|AIMS_inverter_control_via_GPIO_ports]] I built
+earlier.
+
+This kind of automation is a perfect fit for Functional Reactive
+Programming (FRP) since it's all about time-varying behaviors and events
+being combined together.
+
+Of course, I want the control code to be as robust as possible, well
+tested, and easy to modify without making mistakes. Pure functional Haskell
+code.
+
+There are many Haskell libraries for FRP, and I have not looked at most of
+them in any detail. I settled on
+[reactive-banana](https://wiki.haskell.org/Reactive-banana) because it
+has a good reputation and amazing testimonials. 
+<img src="https://wiki.haskell.org/wikiupload/7/7c/Reactive-Banana-banana.png">
+
+> "In the programming-language world, one rule of survival is simple:
+> dance or die. This library makes dancing easy." – Simon Banana Jones
+
+But, it's mostly used for GUI programming, or maybe some musical
+live-coding. There were no libraries for using reactive-banana for
+the more staid task of home automation, or anything like that. 
+Also, using it involves a whole lot of IO code, so not great for testing.
+
+So I built
+[reactive-banana-automation](http://hackage.haskell.org/package/reactive-banana-automation) 
+on top of it to address my needs. I think it's a pretty good library,
+although I don't have a deep enough grokking of FRP to say that for sure.
+
+Anyway, it's plenty flexible for my fridge automation needs, and I also
+wrote a motion-controlled light automation with it to make sure it could be
+used for something else (and to partly tackle the problem of using
+real-world time events when the underlying FRP library uses its own
+notion of time).
+
+[The code for my fridge](https://git.joeyh.name/index.cgi/joey/homepower.git/tree/reactive.hs#n72) 
+is a work in progress since the fridge has not arrived yet, and because
+the question of in which situations an offgrid fridge should optimally 
+run and not run is really rather complicated.
+
+Here's a simpler example, for a non-offgrid fridge.
+
+[[!format haskell """
+fridge :: Automation Sensors Actuators
+fridge sensors actuators = do
+        -- Create a Behavior that reflects the most recently reported
+        -- temperature of the fridge.
+        btemperature <- sensedBehavior (fridgeTemperature sensors)
+        -- Calculate when the fridge should turn on and off.
+        let bpowerchange = calcpowerchange <$> btemperature
+        onBehaviorChangeMaybe bpowerchange (actuators . FridgePower)
+  where
+        calcpowerchange (Sensed temp)
+                | temp `belowRange` allowedtemp = Just PowerOff
+                | temp `aboveRange` allowedtemp = Just PowerOn
+                | otherwise = Nothing
+        calcpowerchange SensorUnavailable = Nothing
+        allowedtemp = Range 1 4
+"""]]
+
+And here the code is being tested in a reproducible fashion:
+
+	> runner <- observeAutomation fridge mkSensors
+	> runner $ \sensors -> fridgeTemperature sensors =: 6
+	[FridgePower PowerOn]
+	> runner $ \sensors -> fridgeTemperature sensors =: 3
+	[]
+	> runner $ \sensors -> fridgeTemperature sensors =: 0.5
+	[FridgePower PowerOff]
+
+BTW, building a 400 line library and writing reams of control code for a
+fridge that has not been installed yet is what we Haskell programmers call
+"laziness".
+

rotate
diff --git a/blog/pics/aimsinvertercontrol.jpg b/blog/pics/aimsinvertercontrol.jpg
index 4ea4d086..30c8de7e 100644
Binary files a/blog/pics/aimsinvertercontrol.jpg and b/blog/pics/aimsinvertercontrol.jpg differ

scale
diff --git a/blog/entry/AIMS_inverter_control_via_GPIO_ports.mdwn b/blog/entry/AIMS_inverter_control_via_GPIO_ports.mdwn
index 784b8473..824a6187 100644
--- a/blog/entry/AIMS_inverter_control_via_GPIO_ports.mdwn
+++ b/blog/entry/AIMS_inverter_control_via_GPIO_ports.mdwn
@@ -27,8 +27,8 @@ letting it turn the inverter on and off, and also check if it's currently
 running. Built this board, which is the first PCB I've designed and built
 myself.
 
-[[!img pics/aimsinvertercontrol.jpg size=640x]]
-[[!img pics/aimsinvertercontrolschematic.jpg size=640x]]
+[[!img pics/aimsinvertercontrol.jpg size=400x]]
+[[!img pics/aimsinvertercontrolschematic.jpg size=400x]]
 
 The full schematic and haskell code to control the inverter are in
 the git repository <https://git.joeyh.name/index.cgi/joey/homepower.git/tree/>.

scale
diff --git a/blog/entry/AIMS_inverter_control_via_GPIO_ports.mdwn b/blog/entry/AIMS_inverter_control_via_GPIO_ports.mdwn
index 31071ee5..784b8473 100644
--- a/blog/entry/AIMS_inverter_control_via_GPIO_ports.mdwn
+++ b/blog/entry/AIMS_inverter_control_via_GPIO_ports.mdwn
@@ -28,7 +28,7 @@ running. Built this board, which is the first PCB I've designed and built
 myself.
 
 [[!img pics/aimsinvertercontrol.jpg size=640x]]
-[[!img pics/aimsinvertercontrolschematic.jpg]]
+[[!img pics/aimsinvertercontrolschematic.jpg size=640x]]
 
 The full schematic and haskell code to control the inverter are in
 the git repository <https://git.joeyh.name/index.cgi/joey/homepower.git/tree/>.

oops
diff --git a/blog/pics/aimsinvertercontrolschematic.jpg b/blog/pics/aimsinvertercontrolschematic.jpg
new file mode 100644
index 00000000..9b0bbc6f
Binary files /dev/null and b/blog/pics/aimsinvertercontrolschematic.jpg differ

blog update
diff --git a/blog/entry/AIMS_inverter_control_via_GPIO_ports.mdwn b/blog/entry/AIMS_inverter_control_via_GPIO_ports.mdwn
new file mode 100644
index 00000000..31071ee5
--- /dev/null
+++ b/blog/entry/AIMS_inverter_control_via_GPIO_ports.mdwn
@@ -0,0 +1,45 @@
+I recently upgraded my inverter to a AIMS 1500 watt pure sine inverter
+(PWRI150024S). This is a decent inverter for the price, I hope.
+It seems reasonably efficient under load compared to other inverters. 
+But when it's fully idle, it still consumes 4 watts of power. 
+
+That's almost as much power as my laptop, and while 96 watt-hours per day 
+may not sound like a lot of power, some days in winter, 100 watt-hours is
+my entire budget for the day. Adding more batteries just to power an idle
+inverter would be the normal solution, probably. Instead, I want to have my
+house computer turn it off when it's not being used.
+
+Which comes to the other problem with this inverter, since the power
+control is not a throw switch, but a button you have to press and hold for
+a second. And looking inside the inverter, this was not easily hacked to
+add a relay to control it.
+
+The inverter has a RJ22 control port. AIMS also does not seem to document
+what the pins do, so I reverse engineered them.
+
+Since the power is toggled, it's important that the computer be able to
+check if the inverter is currently running, to reliably get to the desired
+on/off state.
+
+I designed (well, mostly cargo-culted) a circuit that uses 4n35
+optoisolators to safely interface the AIMS with my cubietruck's GPIO ports,
+letting it turn the inverter on and off, and also check if it's currently
+running. Built this board, which is the first PCB I've designed and built
+myself.
+
+[[!img pics/aimsinvertercontrol.jpg size=640x]]
+[[!img pics/aimsinvertercontrolschematic.jpg]]
+
+The full schematic and haskell code to control the inverter are in
+the git repository <https://git.joeyh.name/index.cgi/joey/homepower.git/tree/>.
+My design notebook for this build is [available in secure scuttlebutt](https://viewer.scuttlebot.io/%25EvpWKGJyYIuSiOr3WjDsBCVHLIkt5Ncqd7lBsLX%2B9bs%3D.sha256)
+along with [power consumption measurements](https://viewer.scuttlebot.io/%25lPj7KktYPERL4N3WpF64UXFjcj19mDpt5F1YVblYi2k%3D.sha256).
+
+It works!
+
+	joey@darkstar:~>ssh house inverter status
+	off
+	joey@darkstar:~>ssh house inverter on
+	joey@darkstar:~>ssh house inverter status
+	on
+
diff --git a/blog/pics/aimsinvertercontrol.jpg b/blog/pics/aimsinvertercontrol.jpg
new file mode 100644
index 00000000..4ea4d086
Binary files /dev/null and b/blog/pics/aimsinvertercontrol.jpg differ

add talk
diff --git a/talks.mdwn b/talks.mdwn
index d0c2d0e8..aa770a1a 100644
--- a/talks.mdwn
+++ b/talks.mdwn
@@ -115,3 +115,8 @@ by others.
   - [[slides|debconf-17-life-after-debian.pdf]]
   - Correction: The other propellor developer in the audience of this talk,
     who I referred to as "Simon", was actually Sean Whitton.
+
+## Libreplanet 2017, MIT
+
+* "Secure Scuttlebutt lightning talk"
+  - [video](https://downloads.kitenet.net/talks/secure-scuttlebutt-lightning-talk-libreplanet.webm)

meh
diff --git a/blog/entry/three_conferences_one_week.mdwn b/blog/entry/three_conferences_one_week.mdwn
index 610f778c..ca683203 100644
--- a/blog/entry/three_conferences_one_week.mdwn
+++ b/blog/entry/three_conferences_one_week.mdwn
@@ -34,4 +34,4 @@ visit with me and go to a FP conference too.
 
 And now time to retreat into my retreaty place for a good long while.
 
-[[!img pics/springleaves.jpg size=1024x]]
+[[!img pics/springleaves.jpg size=764x]]

meh
diff --git a/blog/entry/three_conferences_one_week.mdwn b/blog/entry/three_conferences_one_week.mdwn
index 11fe707c..610f778c 100644
--- a/blog/entry/three_conferences_one_week.mdwn
+++ b/blog/entry/three_conferences_one_week.mdwn
@@ -34,4 +34,4 @@ visit with me and go to a FP conference too.
 
 And now time to retreat into my retreaty place for a good long while.
 
-[[!img size=1024x pics/springleaves.jpg]]
+[[!img pics/springleaves.jpg size=1024x]]

scale
diff --git a/blog/entry/three_conferences_one_week.mdwn b/blog/entry/three_conferences_one_week.mdwn
index 2387e771..11fe707c 100644
--- a/blog/entry/three_conferences_one_week.mdwn
+++ b/blog/entry/three_conferences_one_week.mdwn
@@ -34,4 +34,4 @@ visit with me and go to a FP conference too.
 
 And now time to retreat into my retreaty place for a good long while.
 
-[[!img pics/springleaves.jpg]]
+[[!img size=1024x pics/springleaves.jpg]]

pic
diff --git a/blog/entry/three_conferences_one_week.mdwn b/blog/entry/three_conferences_one_week.mdwn
index fa817052..2387e771 100644
--- a/blog/entry/three_conferences_one_week.mdwn
+++ b/blog/entry/three_conferences_one_week.mdwn
@@ -33,3 +33,5 @@ another Lambda Squared next year, and this might be a good opportunity to
 visit with me and go to a FP conference too.
 
 And now time to retreat into my retreaty place for a good long while.
+
+[[!img pics/springleaves.jpg]]
diff --git a/blog/pics/springleaves.jpg b/blog/pics/springleaves.jpg
new file mode 100644
index 00000000..b7f43e85
Binary files /dev/null and b/blog/pics/springleaves.jpg differ

post
diff --git a/blog/entry/three_conferences_one_week.mdwn b/blog/entry/three_conferences_one_week.mdwn
index 05acb54f..fa817052 100644
--- a/blog/entry/three_conferences_one_week.mdwn
+++ b/blog/entry/three_conferences_one_week.mdwn
@@ -1,34 +1,35 @@
 Thought I'd pack my entire year's conference schedule into one week...
 
-First was a Neuroinformatics infrastructure interoperability workshop at
-McGill, my second trip to Montreal this year. Well outside my wheelhouse,
-but there's a fair amount of interest in that community in git-annex/datalad.
-This was a roll with the acronyms, and try to draw parallels to things I know
-affair. Also excellent sushi and a bonus Secure Scuttlebutt meetup.
+First was a [Neuroinformatics infrastructure interoperability
+workshop](https://www.incf.org/node/272) at McGill, my second trip to
+Montreal this year. Well outside my wheelhouse, but there's a fair amount
+of interest in that community in git-annex/datalad. This was a roll with
+the acronyms, and try to draw parallels to things I know affair. Also
+excellent sushi and a bonus Secure Scuttlebutt meetup.
 
-Then LibrePlanet. A unique and super special conference, that utterly flew
-by this year. This is my sixth LibrePlanet and I enjoy it more each time.
-Hghlights for me were Bassam's photogrammetry workshop, Karen receiving
-the Free Software award, and Seth's thought-provoking talk on
-"incompossibilities". And some epic dinner conversations.
+Then [LibrePlanet](https://libreplanet.org/2018). A unique and super special
+conference, that utterly flew by this year. This is my sixth LibrePlanet
+and I enjoy it more each time. Hghlights for me were Bassam's
+photogrammetry workshop, Karen receiving the Free Software award, and
+Seth's thought-provoking talk on "incompossibilities" especially as applied
+to social networks. And some epic dinner conversations in central square.
 
-Finally today, a one-day localish(!) functional programming(!!) conference
-in Knoxville TN. Lambda Squared was the best constructed single-track
-conference I've seen. Starting with an ex-pro-figure skater getting the
-whole audience to pirouette to capture that uncomfortable out of your
-element feeling you get learning FP, and ramping gradually past "functional
-javascript" to orthagonality, cofunctors, the type system cube, and
-constructionalism.
+Finally today, a one-day local(!) functional programming(!!) conference
+in Knoxville TN. [Lambda Squared](https://www.lambda-squared.com/schedule)
+was the best constructed single-track conference I've seen. Starting with
+an ex-pro-figure skater getting the [whole audience to
+pirouette](https://twitter.com/Aimee_Knight/status/979772267487023104) to
+capture that uncomfortable out of your element feeling you get learning FP,
+and ramping gradually past "functional javascript" to orthagonality,
+contravariant functors, the lambda cube, and constructivist logic.
 
-There are not a lot of functional programming conferences in the
-southeastern USA, and I think this explains how Lambda Squared attracted
-such a good lineup of speakers. Also Knoxville has a surprisingly large and
-lively FP community forming, which has been a surprise to me as I never get
-over there. There will be another Lambda Squared next year, and this
-might be a good opportunity to visit with me and go to a FP conference too.
-
-(Also I finally managed to talk to a geologist about entropy and rocks. At
-the FP conference of all places. I want to talk to more geologists about
-entropy and rocks. The reason is obvious I assume...)
+I notice that I've spent a lot more time in Boston than I ever have in
+Knoxville -- Cambridge MA is starting to feel like my old haunts, though
+I've never really lived there. There are not a lot of functional
+programming conferences in the southeastern USA, and I think this explains
+how Lambda Squared attracted such a good lineup of speakers. Also Knoxville
+has a surprisingly large and lively FP community shaping up. There will be
+another Lambda Squared next year, and this might be a good opportunity to
+visit with me and go to a FP conference too.
 
 And now time to retreat into my retreaty place for a good long while.

blog update
diff --git a/blog/entry/three_conferences_one_week.mdwn b/blog/entry/three_conferences_one_week.mdwn
new file mode 100644
index 00000000..05acb54f
--- /dev/null
+++ b/blog/entry/three_conferences_one_week.mdwn
@@ -0,0 +1,34 @@
+Thought I'd pack my entire year's conference schedule into one week...
+
+First was a Neuroinformatics infrastructure interoperability workshop at
+McGill, my second trip to Montreal this year. Well outside my wheelhouse,
+but there's a fair amount of interest in that community in git-annex/datalad.
+This was a roll with the acronyms, and try to draw parallels to things I know
+affair. Also excellent sushi and a bonus Secure Scuttlebutt meetup.
+
+Then LibrePlanet. A unique and super special conference, that utterly flew
+by this year. This is my sixth LibrePlanet and I enjoy it more each time.
+Hghlights for me were Bassam's photogrammetry workshop, Karen receiving
+the Free Software award, and Seth's thought-provoking talk on
+"incompossibilities". And some epic dinner conversations.
+
+Finally today, a one-day localish(!) functional programming(!!) conference
+in Knoxville TN. Lambda Squared was the best constructed single-track
+conference I've seen. Starting with an ex-pro-figure skater getting the
+whole audience to pirouette to capture that uncomfortable out of your
+element feeling you get learning FP, and ramping gradually past "functional
+javascript" to orthagonality, cofunctors, the type system cube, and
+constructionalism.
+
+There are not a lot of functional programming conferences in the
+southeastern USA, and I think this explains how Lambda Squared attracted
+such a good lineup of speakers. Also Knoxville has a surprisingly large and
+lively FP community forming, which has been a surprise to me as I never get
+over there. There will be another Lambda Squared next year, and this
+might be a good opportunity to visit with me and go to a FP conference too.
+
+(Also I finally managed to talk to a geologist about entropy and rocks. At
+the FP conference of all places. I want to talk to more geologists about
+entropy and rocks. The reason is obvious I assume...)
+
+And now time to retreat into my retreaty place for a good long while.

fixup: forgot signature
diff --git a/code/moreutils/discussion.mdwn b/code/moreutils/discussion.mdwn
index ac56507b..d54ca26b 100644
--- a/code/moreutils/discussion.mdwn
+++ b/code/moreutils/discussion.mdwn
@@ -16,6 +16,8 @@ I'm running "chronic fetchmail" in my crontab and I'd like to discard exit code
 The method proposed in fetchmail's man page is to run "chronic sh -c 'fetchmail || [ $? -eq 1 ]'" but I'd prefer something like "chronic -i 1 fetchmail", because this avoids the separate shell and allows to discard several exit codes (think of rsync's various possibly unimportant errors).
 I'll try to come up with a patch if this is desired.
 
+-- deep42thought
+
 ### triggering with zero exit code
 
 I've a use case where I want chronic to work in exactly the opposite fashion: to throw away stdout/stderr if and only if the exit code is non-zero. I could obviously do this with a wrapper script that inverts the exit code, but that (a) means I only know whether the command I ran had a zero/non-zero exit code, not what it was, and (b) means there's an unnecessary layer between chronic and the command.

proposal: chronic: ignore (selected) non-zero exit codes
diff --git a/code/moreutils/discussion.mdwn b/code/moreutils/discussion.mdwn
index 5d34e00c..ac56507b 100644
--- a/code/moreutils/discussion.mdwn
+++ b/code/moreutils/discussion.mdwn
@@ -10,6 +10,12 @@ It put it up on [github here](https://github.com/girst/forkaftergrep)
 
 ## chronic
 
+### discarding certain non-zero exit codes
+
+I'm running "chronic fetchmail" in my crontab and I'd like to discard exit code 1 - "no new mail".
+The method proposed in fetchmail's man page is to run "chronic sh -c 'fetchmail || [ $? -eq 1 ]'" but I'd prefer something like "chronic -i 1 fetchmail", because this avoids the separate shell and allows to discard several exit codes (think of rsync's various possibly unimportant errors).
+I'll try to come up with a patch if this is desired.
+
 ### triggering with zero exit code
 
 I've a use case where I want chronic to work in exactly the opposite fashion: to throw away stdout/stderr if and only if the exit code is non-zero. I could obviously do this with a wrapper script that inverts the exit code, but that (a) means I only know whether the command I ran had a zero/non-zero exit code, not what it was, and (b) means there's an unnecessary layer between chronic and the command.

Added a comment: ethics and open source
diff --git a/blog/entry/prove_you_are_not_an_Evil_corporate_person/comment_3_aae1b5869c77a78bdddc14bf8f754e4c._comment b/blog/entry/prove_you_are_not_an_Evil_corporate_person/comment_3_aae1b5869c77a78bdddc14bf8f754e4c._comment
new file mode 100644
index 00000000..a9c4edc0
--- /dev/null
+++ b/blog/entry/prove_you_are_not_an_Evil_corporate_person/comment_3_aae1b5869c77a78bdddc14bf8f754e4c._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="paolo.greppi@1e21b72a79d4a7d7ea51729cfb52e8d00557ccd4"
+ nickname="paolo.greppi"
+ avatar="http://cdn.libravatar.org/avatar/068b9627eda3ed0b35fecd432dcac210"
+ subject="ethics and open source"
+ date="2018-03-14T18:57:05Z"
+ content="""
+Google Inc may be opposed to AGPL but other interested parties may well happily take it.
+
+I think you are misusing an open source license to achieve an **ethical purpose**.
+
+If you want to be 100% sure that your open source work is not used for “*evil*” you could add to the license the line \"*The Software shall be used for Good, not Evil*\" (see [JSLint](https://en.wikipedia.org/wiki/JSLint#License)).
+
+But then who checks what is \"*evil*\"?
+
+You probably need to set up a bureaucracy with \"*certificates*\" issued by independent third partes do demonstrate that the purpose is \"*not evil*\" (as you need if you want to sell \"*organic*\" food).
+"""]]

no
diff --git a/blog/entry/prove_you_are_not_an_Evil_corporate_person/comment_2_696cc0f17e5de956d048ebe0efe53592._comment b/blog/entry/prove_you_are_not_an_Evil_corporate_person/comment_2_696cc0f17e5de956d048ebe0efe53592._comment
new file mode 100644
index 00000000..3c9ccd8c
--- /dev/null
+++ b/blog/entry/prove_you_are_not_an_Evil_corporate_person/comment_2_696cc0f17e5de956d048ebe0efe53592._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""re: above kilobyte of nonsense"""
+ date="2018-03-13T14:36:45Z"
+ content="""
+The AGPL is a DFSG compliant license; all of my AGPL
+licensed software is in fact distributed in Debian.
+"""]]

Added a comment: DFSG#5 and #6
diff --git a/blog/entry/prove_you_are_not_an_Evil_corporate_person/comment_1_b17538f3c01328df7c1d9f6c7ed39ce3._comment b/blog/entry/prove_you_are_not_an_Evil_corporate_person/comment_1_b17538f3c01328df7c1d9f6c7ed39ce3._comment
new file mode 100644
index 00000000..a4f195e0
--- /dev/null
+++ b/blog/entry/prove_you_are_not_an_Evil_corporate_person/comment_1_b17538f3c01328df7c1d9f6c7ed39ce3._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="kilobyte@ae5b544234799453020139b13729c204af96255d"
+ nickname="kilobyte"
+ avatar="http://cdn.libravatar.org/avatar/df4ea9661bdbcda2f6c65ef48902645b"
+ subject="DFSG#5 and #6"
+ date="2018-03-12T22:58:29Z"
+ content="""
+This sounds like a very clear-cut violation of DFSG#5 and #6.  You're
+discriminating against using the software for military purposes.
+
+Well, this is the same Google that discriminates against anyone who's
+looking to purchase a gun or anything unrelated that just happens to have
+\"gun\" as part of a word in its name (yet something denying cakes for gay
+weddings is a legal argument used by them), but two wrongs don't make a
+right.
+
+There's also a question whether AGPL is a free software license at all.
+I believe it's not: fails FSF Freedom 0 (networked light switch; IMAP
+server) and the Dissident Test (a dissident hiding steganographic messages
+on a blogging platform with thousands of unrelated users; only fellow
+dissidents receive a module to encrypt/decrypt the messages).
+
+"""]]

avoid rescale
diff --git a/blog/entry/prove_you_are_not_an_Evil_corporate_person.mdwn b/blog/entry/prove_you_are_not_an_Evil_corporate_person.mdwn
index b32ad9e3..62f88287 100644
--- a/blog/entry/prove_you_are_not_an_Evil_corporate_person.mdwn
+++ b/blog/entry/prove_you_are_not_an_Evil_corporate_person.mdwn
@@ -1,6 +1,6 @@
 In which Google be Google and I drop a hot AGPL tip.
 
-[[!img pics/recaptcha.png]]
+[[pics/recaptcha.png]]
 
 [Google Is Quietly Providing AI Technology for Drone Strike Targeting Project](https://theintercept.com/2018/03/06/google-is-quietly-providing-ai-technology-for-drone-strike-targeting-project/)  
 [Google Is Helping the Pentagon Build AI for Drones](https://gizmodo.com/google-is-helping-the-pentagon-build-ai-for-drones-1823464533)

smaller
diff --git a/blog/pics/recaptcha.png b/blog/pics/recaptcha.png
index 4c1a40f0..f187c7d3 100644
Binary files a/blog/pics/recaptcha.png and b/blog/pics/recaptcha.png differ

blog update
diff --git a/blog/entry/prove_you_are_not_an_Evil_corporate_person.mdwn b/blog/entry/prove_you_are_not_an_Evil_corporate_person.mdwn
new file mode 100644
index 00000000..b32ad9e3
--- /dev/null
+++ b/blog/entry/prove_you_are_not_an_Evil_corporate_person.mdwn
@@ -0,0 +1,62 @@
+In which Google be Google and I drop a hot AGPL tip.
+
+[[!img pics/recaptcha.png]]
+
+[Google Is Quietly Providing AI Technology for Drone Strike Targeting Project](https://theintercept.com/2018/03/06/google-is-quietly-providing-ai-technology-for-drone-strike-targeting-project/)  
+[Google Is Helping the Pentagon Build AI for Drones](https://gizmodo.com/google-is-helping-the-pentagon-build-ai-for-drones-1823464533)
+
+> to automate the identification and classification of images taken
+> by drones — cars, buildings, people — providing analysts with increased
+> ability to make informed decisions on the battlefield
+
+These news reports don't mention reCaptcha explicitly, but it's been asking
+about a lot of cars lately. Whatever the source of the data that Google is
+using for this, it's disgusting that they're mining it from us without our
+knowledge or consent.
+
+Google claims that "The technology flags images for human review, and is
+for non-offensive uses only". So, if a drone operator has a neural network
+that we all were tricked & coerced into training to identify cars and
+people helping to highlight them on their screen and center the crosshairs
+just right, and the neural network is not pressing the kill switch, is it
+being used for "non-offensive purposes only"?
+
+---
+
+Google is known to be 
+[deathly allergic to the AGPL license](https://opensource.google.com/docs/using/agpl-policy/). 
+Not only on servers; they don't even allow employees to use AGPL
+software on workstations. If you write free software, and you'd prefer
+that Google not use it, a good way to ensure that is to license it
+under the AGPL.
+
+I normally try to respect the privacy of users of my software, and of
+personal conversations. But at this point, I feel that
+Google's behavior has mostly obviated those moral obligations. So...
+
+Now seems like a good time to mention that I have been contacted by
+multiple people at Google about several of my AGPL licensed projects
+(git-annex and either keysafe or debug-me I can't remember which)
+trying to get me to switch them to the GPL, and had long conversations with
+them about it.
+
+Google has some legal advice that the AGPL source provision triggers much
+more often than it's commonly understood to. I encouraged them to make that
+legal reasoning public, so the community could address/debunk it, but I
+don't think they have. I won't go into details about it here, other than it
+seemed pretty bonkers.
+
+Mixing in some AGPL code with an otherwise GPL codebase also seems
+sufficient to trigger Google's allergy. In the case of git-annex, it's
+possible to build all releases (until next month's) with a flag that prevents
+linking with any AGPL code, which should mean the resulting binary is GPL
+licensed, but Google still didn't feel able to use it, since the git-annex
+source tree includes AGPL files.
+
+I don't know if Google's allergy to the AGPL extends to software used for
+drone murder applications, but in any case I look forward to preventing
+Google from using more of my software in the future.
+
+---
+
+(Illustration by [scatter//gather](https://freeradical.zone/@scattergather))
diff --git a/blog/pics/recaptcha.png b/blog/pics/recaptcha.png
new file mode 100644
index 00000000..4c1a40f0
Binary files /dev/null and b/blog/pics/recaptcha.png differ