Recent changes to this wiki:

add
diff --git a/pics/linux.conf.au/presenting.jpg b/pics/linux.conf.au/presenting.jpg
new file mode 100644
index 0000000..dd4f89a
Binary files /dev/null and b/pics/linux.conf.au/presenting.jpg differ
diff --git a/talks/keysafe.pdf b/talks/keysafe.pdf
new file mode 100644
index 0000000..c391aec
Binary files /dev/null and b/talks/keysafe.pdf differ
diff --git a/talks/propellor.pdf b/talks/propellor.pdf
new file mode 100644
index 0000000..c4e6265
Binary files /dev/null and b/talks/propellor.pdf differ

Added a comment: tmux's API and ii
diff --git a/blog/entry/multi-terminal_applications/comment_8_8b2ae6bd51f144027c0a895c798eda5d._comment b/blog/entry/multi-terminal_applications/comment_8_8b2ae6bd51f144027c0a895c798eda5d._comment
new file mode 100644
index 0000000..ab36688
--- /dev/null
+++ b/blog/entry/multi-terminal_applications/comment_8_8b2ae6bd51f144027c0a895c798eda5d._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="anarcat"
+ avatar="http://cdn.libravatar.org/avatar/4ad594c1e13211c1ad9edb81ce5110b7"
+ subject="tmux's API and ii"
+ date="2017-01-17T18:40:13Z"
+ content="""
+i have a similar concern in a project i'm working on now, which is to
+run a bunch of tests in one window and showing system logs in another
+window for convenience. i thought i would use tmux for this because the
+commandline interface is simple enough to be used like an API. my
+previous approach to this was to use a multi-interface design with
+simple functions like \"alert\", \"prompt\" or \"log\" that would send stuff
+to different places (terminal or gtk windows) depending on the
+environment, a bit like what debconf is doing, with all the crap that
+implies (generally: a suboptimal interface everywhere).
+
+as for an irc client, you may be curious to try out `ii`: it's a simple
+FIFO and filesystem-based irc client that implements basically *no* user
+interface... a little nuts, but sounds like it would be the backend to
+the UI you are describing.
+
+"""]]

Added a comment: flatpak?
diff --git a/blog/entry/completely_linux_distribution-independent_packaging/comment_4_8938ef07b70cde4a9427b16ed1668222._comment b/blog/entry/completely_linux_distribution-independent_packaging/comment_4_8938ef07b70cde4a9427b16ed1668222._comment
new file mode 100644
index 0000000..b0d33f0
--- /dev/null
+++ b/blog/entry/completely_linux_distribution-independent_packaging/comment_4_8938ef07b70cde4a9427b16ed1668222._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="anarcat"
+ avatar="http://cdn.libravatar.org/avatar/4ad594c1e13211c1ad9edb81ce5110b7"
+ subject="flatpak?"
+ date="2017-01-17T18:38:26Z"
+ content="""
+this is awesome. :) i have used this in weird cases (which, unfortunately, now include debian jessie ;) and bundle at least one of those binaries next to my git-annex archives...
+
+it seems there's a new player in this problem space - did you look at [flatpak](http://flatpak.org/)? the haskell folks have started to [consider it](https://github.com/haskell/haskell-platform/issues/259)...
+"""]]

fix more
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 04c71a0..8fe9073 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -38,7 +38,7 @@ Keysafe's server list puts servers in three categories:
 
 ### Recommended
 
-* hlmjmeth356s5ekm.onion
+#### hlmjmeth356s5ekm.onion
 
 	-----BEGIN PGP SIGNED MESSAGE-----
 	Hash: SHA1
@@ -72,7 +72,7 @@ Keysafe's server list puts servers in three categories:
 
 ### Alternate
 
-* keysafe.joeyh.name
+#### keysafe.joeyh.name
 
 	-----BEGIN PGP SIGNED MESSAGE-----
 	Hash: SHA256
@@ -104,7 +104,7 @@ Keysafe's server list puts servers in three categories:
 	-----END PGP SIGNATURE-----
 </pre>
 
-* thirdserver
+#### thirdserver
 
   Provided by Marek Isalski at [Faelix](http://www.faelix.net/).
   Currently located in UK, but planned move to CH.  

fix formatting so warrent canary link works
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index c1553c7..04c71a0 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -40,71 +40,68 @@ Keysafe's server list puts servers in three categories:
 
 * hlmjmeth356s5ekm.onion
 
-<pre>
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-The keysafe server hlmjmeth356s5ekm.onion is provided and administered by
-Purism. It is located in the EU (Cyprus).
-
-We intend to run this server for at least 10 years (through 2027),
-or failing that, to transition any data stored on it to another
-server that is of similar or higher security.
-
-Our warrant canary is <https://puri.sm/warrant-canary/>,
-and is updated quarterly.
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1
-
-iQIcBAEBAgAGBQJYF8U4AAoJECPPLj0lRRT30CkP/Rn2TAeriNWO9wZcr0OHyX7B
-TJcgLy3pZXbGn6T6qmJqg3K22fTKJ7CX0dfIM+WLI9FfBtnT95q1rnzywhBGPXzj
-eD3g7r3QinIfMLBQTKyc9Ik5132uenD5h72ggVl3D+kuWv622IhaAaiVkuHc5KoR
-3/S+ImkcS/gz83UNTXnWdMs0V8+eqAjpWeYQS8Ih28AECI9f+xUUH//V9Ii/4Usv
-E3Y0hbqj8kSi4/Q6IwmFiJTKZ1FpccKhl6GIYUSLwJMJDHoI46M/AaZy0Xx9pLcU
-niSELai/7/0fY4N0TY2CbZUgH7FEhi0k8cCsGF7yTA6dqya8deKQKdUdDllcHayv
-+GOAqijiSTPrRox4TPMMdurPXTsJxeJuxVdS75Lw2cFk+JaaIVS/3XEyeuGpaVKW
-wSTltyFkMx9ur5cCPT2rxoRN78HuqgiHda/Jd4c2pny7GwpUEYAznQQaBYEl2jlQ
-/Go3ZudpnWfBRRe7znazhA6mIatPY61GrNIebVlET6/NCw9sZFRjHXY3pMw1u/TY
-4eP0UQpBUed4/sot5vsZVwbn8e6eFh0S4HTdl5x1G8jN8nUZVdJJjOtACrONW+TG
-CLSNDkMgQ5slBmtZm+MzL2VYkFHCMmPerNXY1DhHjMyfLpQEIN+bho+mIyc5h/W/
-Br5jFZujcQ0u7GzqvaDB
-=RmK4
------END PGP SIGNATURE-----
-</pre>
+	-----BEGIN PGP SIGNED MESSAGE-----
+	Hash: SHA1
+	
+	The keysafe server hlmjmeth356s5ekm.onion is provided and administered by
+	Purism. It is located in the EU (Cyprus).
+	
+	We intend to run this server for at least 10 years (through 2027),
+	or failing that, to transition any data stored on it to another
+	server that is of similar or higher security.
+	
+	Our warrant canary is <https://puri.sm/warrant-canary/>,
+	and is updated quarterly.
+	-----BEGIN PGP SIGNATURE-----
+	Version: GnuPG v1
+	
+	iQIcBAEBAgAGBQJYF8U4AAoJECPPLj0lRRT30CkP/Rn2TAeriNWO9wZcr0OHyX7B
+	TJcgLy3pZXbGn6T6qmJqg3K22fTKJ7CX0dfIM+WLI9FfBtnT95q1rnzywhBGPXzj
+	eD3g7r3QinIfMLBQTKyc9Ik5132uenD5h72ggVl3D+kuWv622IhaAaiVkuHc5KoR
+	3/S+ImkcS/gz83UNTXnWdMs0V8+eqAjpWeYQS8Ih28AECI9f+xUUH//V9Ii/4Usv
+	E3Y0hbqj8kSi4/Q6IwmFiJTKZ1FpccKhl6GIYUSLwJMJDHoI46M/AaZy0Xx9pLcU
+	niSELai/7/0fY4N0TY2CbZUgH7FEhi0k8cCsGF7yTA6dqya8deKQKdUdDllcHayv
+	+GOAqijiSTPrRox4TPMMdurPXTsJxeJuxVdS75Lw2cFk+JaaIVS/3XEyeuGpaVKW
+	wSTltyFkMx9ur5cCPT2rxoRN78HuqgiHda/Jd4c2pny7GwpUEYAznQQaBYEl2jlQ
+	/Go3ZudpnWfBRRe7znazhA6mIatPY61GrNIebVlET6/NCw9sZFRjHXY3pMw1u/TY
+	4eP0UQpBUed4/sot5vsZVwbn8e6eFh0S4HTdl5x1G8jN8nUZVdJJjOtACrONW+TG
+	CLSNDkMgQ5slBmtZm+MzL2VYkFHCMmPerNXY1DhHjMyfLpQEIN+bho+mIyc5h/W/
+	Br5jFZujcQ0u7GzqvaDB
+	=RmK4
+	-----END PGP SIGNATURE-----
 
 ### Alternate
 
 * keysafe.joeyh.name
 
-<pre>
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA256
-
-  keysafe.joeyh.name is provided by me, Joey Hess.
-
-  I intend to run this server for at least 10 years (through 2027),
-  or failing that, to transition any data stored on it to another
-  server that is of similar or higher security.
-
-  It is a Digital Ocean VPS, located in Indonesia. I can't tell if the
-  hosting provider is accessing the contents of the server, and so
-  this server is not securely hosted enough to be Recommended.
------BEGIN PGP SIGNATURE-----
-
-iQIcBAEBCAAGBQJXx0qFAAoJEMkQ2SIlEuPHyGMQALSLL7LZEpTi+zf2kPYGoBMQ
-3z3FDB9B6SaF4uN3r+XlAw2Vzas2KVLCbNkO+np7tLzC0qdY5dBLDI7+ZJXiKi2v
-iqxKICl0E8+ih8JOe0JWfoysO974I1DesEI7X6VUewwNpd35OgCuIL5RmknKrX4I
-x7gUfsONiojUKgOT0yMErUfw3VNYB0Kbzw4Xic66eIkFl5z6APMknjqvOC1196v9
-BW0rSM+OsthB9xkj7ULKQv+1LrxmwNu0+FL62qNKGObbXHayfLBGm8TT9Y7etQYD
-3zRDiUfa0m2aYu7ZRx5HSIgExVVd3YosDUFA4xsIb6N4wBbP1zS2TG2Zo5o/+3gt
-BerkQL/xkMWhIMVCYp1hWc47MenHk1MJU5EhS+duL/fnlqW2HcFanM+fOv+/ZWt6
-da2mdjSR95Ekq22BXN9eHO54AFJKLWYNdT9E5W2rlwqUoC4dqsqYGT3XWnAaKHC/
-he9+B/wdEf7165Qy+MKo/36Ib7pfhPQv4hip2cuMP9w0E6JoKZusBV5AdxRvGAGf
-GvUhvNog6v9/t+cqUp6dSTT2WVllkXJ/5deGJYLzZMJjZS3cZ75ZKr8OD5oQxr+m
-7oL6BDvxha7Q4qHo/RZgxyd/qZ7zWHTT6Tn6qNCBGUi4b6Etb0kEd5Os66WoLCSK
-lhmhvShr0WRqB8fWYPkc
-=SNGN
------END PGP SIGNATURE-----
+	-----BEGIN PGP SIGNED MESSAGE-----
+	Hash: SHA256
+	
+	  keysafe.joeyh.name is provided by me, Joey Hess.
+	
+	  I intend to run this server for at least 10 years (through 2027),
+	  or failing that, to transition any data stored on it to another
+	  server that is of similar or higher security.
+	
+	  It is a Digital Ocean VPS, located in Indonesia. I can't tell if the
+	  hosting provider is accessing the contents of the server, and so
+	  this server is not securely hosted enough to be Recommended.
+	-----BEGIN PGP SIGNATURE-----
+	
+	iQIcBAEBCAAGBQJXx0qFAAoJEMkQ2SIlEuPHyGMQALSLL7LZEpTi+zf2kPYGoBMQ
+	3z3FDB9B6SaF4uN3r+XlAw2Vzas2KVLCbNkO+np7tLzC0qdY5dBLDI7+ZJXiKi2v
+	iqxKICl0E8+ih8JOe0JWfoysO974I1DesEI7X6VUewwNpd35OgCuIL5RmknKrX4I
+	x7gUfsONiojUKgOT0yMErUfw3VNYB0Kbzw4Xic66eIkFl5z6APMknjqvOC1196v9
+	BW0rSM+OsthB9xkj7ULKQv+1LrxmwNu0+FL62qNKGObbXHayfLBGm8TT9Y7etQYD
+	3zRDiUfa0m2aYu7ZRx5HSIgExVVd3YosDUFA4xsIb6N4wBbP1zS2TG2Zo5o/+3gt
+	BerkQL/xkMWhIMVCYp1hWc47MenHk1MJU5EhS+duL/fnlqW2HcFanM+fOv+/ZWt6
+	da2mdjSR95Ekq22BXN9eHO54AFJKLWYNdT9E5W2rlwqUoC4dqsqYGT3XWnAaKHC/
+	he9+B/wdEf7165Qy+MKo/36Ib7pfhPQv4hip2cuMP9w0E6JoKZusBV5AdxRvGAGf
+	GvUhvNog6v9/t+cqUp6dSTT2WVllkXJ/5deGJYLzZMJjZS3cZ75ZKr8OD5oQxr+m
+	7oL6BDvxha7Q4qHo/RZgxyd/qZ7zWHTT6Tn6qNCBGUi4b6Etb0kEd5Os66WoLCSK
+	lhmhvShr0WRqB8fWYPkc
+	=SNGN
+	-----END PGP SIGNATURE-----
 </pre>
 
 * thirdserver

Added a comment: I2P is fit for anonymous filesharing by design
diff --git a/blog/entry/p2p_dreams/comment_1_d62b9d0fdcec151eaa2066dc4fe3eaa5._comment b/blog/entry/p2p_dreams/comment_1_d62b9d0fdcec151eaa2066dc4fe3eaa5._comment
new file mode 100644
index 0000000..fae7ef5
--- /dev/null
+++ b/blog/entry/p2p_dreams/comment_1_d62b9d0fdcec151eaa2066dc4fe3eaa5._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="andreas.glaeser@cfd70e43e8acd338681cd069504740fdd4e85b0b"
+ nickname="andreas.glaeser"
+ avatar="http://cdn.libravatar.org/avatar/01527e4b0848adff0e9c052635eaa09b"
+ subject="I2P is fit for anonymous filesharing by design"
+ date="2017-01-15T14:37:09Z"
+ content="""
+Trying out I2P is what I would recommend here, because especially if you are interested in filesharing or anonymous mail-services, this would probably be more cost-efficient, it is said to exist inside the FeeBSD ports-collection.
+So from my perspective TOR is nice for anonymous web-surfing, no idea about onion-services.
+Some big sites closed their services to TOR-users unfortunately, probably because of DDoS-attacks, some even don't accept connections from filtering proxies anymore.
+I2P is still in beta-status AFAIK, but probably one day it is going to be fit for real productive use and match up TOR.
+I2P is a different category, in so far as even the devolpers are anonymous and known by their pseudonyms only.
+
+"""]]

Added a comment: climate change
diff --git a/blog/entry/drought/comment_1_3a8bebf382c4e51c2a322152bc3c787f._comment b/blog/entry/drought/comment_1_3a8bebf382c4e51c2a322152bc3c787f._comment
new file mode 100644
index 0000000..68d9475
--- /dev/null
+++ b/blog/entry/drought/comment_1_3a8bebf382c4e51c2a322152bc3c787f._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="andreas.glaeser@cfd70e43e8acd338681cd069504740fdd4e85b0b"
+ nickname="andreas.glaeser"
+ avatar="http://cdn.libravatar.org/avatar/01527e4b0848adff0e9c052635eaa09b"
+ subject="climate change "
+ date="2017-01-08T13:38:11Z"
+ content="""
+2016 was a record-year globally, as far as I know, even warmer in average than 2015.
+Now, upon break of the new year, there is even snow and ice again in Berlin, and it is supposed to stay this way for three more days at least with temperatures below zero. This is not bad weather in my opinion, but more lovable weather indeed, because far less people are out there to get in your way.
+Sometimes bad weather is good weather in this sense, sometimes cool weather is good weather.
+"""]]

typo
diff --git a/blog/entry/the_cliff.mdwn b/blog/entry/the_cliff.mdwn
index 2a33e75..3bd426b 100644
--- a/blog/entry/the_cliff.mdwn
+++ b/blog/entry/the_cliff.mdwn
@@ -35,4 +35,4 @@ the batteries a perfect chance to recover.
 
 Previously: [[battery_bank_refresh]] [[late_summer]]
 
-[!tag solar]]
+[[!tag solar]]

blog update
diff --git a/blog/entry/the_cliff.mdwn b/blog/entry/the_cliff.mdwn
new file mode 100644
index 0000000..2a33e75
--- /dev/null
+++ b/blog/entry/the_cliff.mdwn
@@ -0,0 +1,38 @@
+Falling off the cliff is always a surprise. I know it's there; I've been
+living next to it for months. I chart its outline daily. Avoiding it has
+become routine, and so comfortable, and so failing to avoid it surprises.
+
+Monday evening around 10 pm, the laptop starts draining down from 100%.
+House battery, which has been steady around 11.5-10.8 volts since well
+before Winter solstice, and was in the low 10's, has plummeted to 8.5 volts.
+
+With the old batteries, the cliff used to be at 7 volts, but now, with
+new batteries but fewer, it's in a surprising place, something like 
+10 volts, and I fell off it.
+
+Weather forecast for the week ahead is much like the previous week: 
+Maybe a couple sunny afternoons, but mostly no sun at all.
+
+Falling off the cliff is not all bad. It shakes things up. It's a good
+opportunity to disconnect, to read paper books, and think long 
+winter thoughts. It forces some flexability.
+
+I have an auxillary battery for these situations. With its own little
+portable solar panel, it can charge the laptop and run it for around 6
+hours. But it takes it several days of winter sun to charge back up.
+
+That's enough to get me through the night. Then I take a short trip, and
+glory in one sunny afternoon. But I know that won't get me out of the hole,
+the batteries need a sunny week to recover. This evening, I expect to lose
+power again, and probably tomorrow evening too.
+
+Luckily, my goal for the week was to write slides for two talks, and I've
+been able to do that despite being mostly offline, and sometimes
+decomputered.
+
+And, in a few days I will be jetting off to Australia! That should give
+the batteries a perfect chance to recover.
+
+Previously: [[battery_bank_refresh]] [[late_summer]]
+
+[!tag solar]]

better link
diff --git a/blog/entry/p2p_dreams.mdwn b/blog/entry/p2p_dreams.mdwn
index 0fd87cf..4d0d83c 100644
--- a/blog/entry/p2p_dreams.mdwn
+++ b/blog/entry/p2p_dreams.mdwn
@@ -106,7 +106,7 @@ for details. Also, the git-annex webapp allows
 [setting the same thing up point-and-click style](http://git-annex.branchable.com/assistant/share_with_a_friend_walkthrough/).
 
 The Tor project blog has throughout December been [featuring all kinds of
-projects that are using Tor](https://blog.torproject.org/blog). 
+projects that are using Tor](https://blog.torproject.org/category/tags/heart-internet-freedom). 
 Consider this a late bonus addition to that. ;) 
 
 I hope that Tor onion services will continue to develop to make them easier
diff --git a/code/keysafe/screenshots/0.png b/code/keysafe/screenshots/0.png
new file mode 100644
index 0000000..7cfe206
Binary files /dev/null and b/code/keysafe/screenshots/0.png differ

Fix word duplicated by mistake.
diff --git a/blog/entry/p2p_dreams.mdwn b/blog/entry/p2p_dreams.mdwn
index 23e8ae1..0fd87cf 100644
--- a/blog/entry/p2p_dreams.mdwn
+++ b/blog/entry/p2p_dreams.mdwn
@@ -77,7 +77,7 @@ Local actions whatsoever. Other interpreters for the Net monad could be
 used to support other network transports than Tor.
 """]]
 
-When when two peers are connected over Tor, one knows it's talking to the
+When two peers are connected over Tor, one knows it's talking to the
 owner of a particular onion address, but the other peer knows nothing about
 who's talking to it, by design. This makes authentication harder than it
 would be in a P2P system with a design like Telehash. 

add
diff --git a/code/keysafe/screenshots/restore/1.png b/code/keysafe/screenshots/restore/1.png
new file mode 100644
index 0000000..8fd1f43
Binary files /dev/null and b/code/keysafe/screenshots/restore/1.png differ
diff --git a/code/keysafe/screenshots/restore/2.png b/code/keysafe/screenshots/restore/2.png
new file mode 100644
index 0000000..e682486
Binary files /dev/null and b/code/keysafe/screenshots/restore/2.png differ
diff --git a/code/keysafe/screenshots/restore/3.png b/code/keysafe/screenshots/restore/3.png
new file mode 100644
index 0000000..7c7e5dc
Binary files /dev/null and b/code/keysafe/screenshots/restore/3.png differ
diff --git a/code/keysafe/screenshots/restore/4.png b/code/keysafe/screenshots/restore/4.png
new file mode 100644
index 0000000..4d07070
Binary files /dev/null and b/code/keysafe/screenshots/restore/4.png differ

calendar update
diff --git a/blog/archives/2017.mdwn b/blog/archives/2017.mdwn
new file mode 100644
index 0000000..bb67a44
--- /dev/null
+++ b/blog/archives/2017.mdwn
@@ -0,0 +1 @@
+[[!calendar type=year year=2017 pages="blog/entry/* and !*/Discussion"]]
diff --git a/blog/archives/2017/01.mdwn b/blog/archives/2017/01.mdwn
new file mode 100644
index 0000000..0899d5b
--- /dev/null
+++ b/blog/archives/2017/01.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=01 year=2017 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(01) and creation_year(2017) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2017/02.mdwn b/blog/archives/2017/02.mdwn
new file mode 100644
index 0000000..5e6001a
--- /dev/null
+++ b/blog/archives/2017/02.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=02 year=2017 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(02) and creation_year(2017) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2017/03.mdwn b/blog/archives/2017/03.mdwn
new file mode 100644
index 0000000..6d0673a
--- /dev/null
+++ b/blog/archives/2017/03.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=03 year=2017 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(03) and creation_year(2017) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2017/04.mdwn b/blog/archives/2017/04.mdwn
new file mode 100644
index 0000000..b08d72d
--- /dev/null
+++ b/blog/archives/2017/04.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=04 year=2017 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(04) and creation_year(2017) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2017/05.mdwn b/blog/archives/2017/05.mdwn
new file mode 100644
index 0000000..de9045c
--- /dev/null
+++ b/blog/archives/2017/05.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=05 year=2017 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(05) and creation_year(2017) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2017/06.mdwn b/blog/archives/2017/06.mdwn
new file mode 100644
index 0000000..4f5be8d
--- /dev/null
+++ b/blog/archives/2017/06.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=06 year=2017 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(06) and creation_year(2017) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2017/07.mdwn b/blog/archives/2017/07.mdwn
new file mode 100644
index 0000000..6c60a4a
--- /dev/null
+++ b/blog/archives/2017/07.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=07 year=2017 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(07) and creation_year(2017) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2017/08.mdwn b/blog/archives/2017/08.mdwn
new file mode 100644
index 0000000..bab88d0
--- /dev/null
+++ b/blog/archives/2017/08.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=08 year=2017 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(08) and creation_year(2017) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2017/09.mdwn b/blog/archives/2017/09.mdwn
new file mode 100644
index 0000000..77d79eb
--- /dev/null
+++ b/blog/archives/2017/09.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=09 year=2017 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(09) and creation_year(2017) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2017/10.mdwn b/blog/archives/2017/10.mdwn
new file mode 100644
index 0000000..e5b1422
--- /dev/null
+++ b/blog/archives/2017/10.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=10 year=2017 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(10) and creation_year(2017) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2017/11.mdwn b/blog/archives/2017/11.mdwn
new file mode 100644
index 0000000..45cadab
--- /dev/null
+++ b/blog/archives/2017/11.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=11 year=2017 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(11) and creation_year(2017) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2017/12.mdwn b/blog/archives/2017/12.mdwn
new file mode 100644
index 0000000..a5a1377
--- /dev/null
+++ b/blog/archives/2017/12.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=12 year=2017 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(12) and creation_year(2017) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]

blog update
diff --git a/blog/entry/p2p_dreams.mdwn b/blog/entry/p2p_dreams.mdwn
new file mode 100644
index 0000000..23e8ae1
--- /dev/null
+++ b/blog/entry/p2p_dreams.mdwn
@@ -0,0 +1,118 @@
+In one of the good parts of the very mixed bag that is "[Lo and Behold:
+Reveries of the Connected World](http://www.loandbehold-film.com/)", 
+Werner Herzog asks his interviewees what the Internet might dream of, if it
+could dream.
+
+The best answer he gets is along the lines of: The Internet of before
+dreamed a dream of the World Wide Web. It dreamed some nodes were
+servers, and some were clients. And that dream became current reality,
+because that's the essence of the Internet.
+
+Three years ago, it seemed like perhaps another dream was developing
+post-Snowden, of dissolving the distinction between clients and servers,
+connecting peer-to-peer using addresses that are also cryptographic public
+keys, so authentication and encryption and authorization are built in.
+
+Telehash is one hopeful attempt at this, others include snow, cjdns, i2p,
+etc. So far, none of them seem to have developed into a widely
+used network, although any of them still might get there. There are a lot
+of technical challenges due to the current Internet dream/nightmare, where
+the peers on the edges have multiple barriers to connecting to other
+peers.
+
+But, one project has developed something similar to the new dream,
+almost as a side effect of its main goals:
+[Tor](https://torproject.org/)'s onion services.
+
+I'd wanted to use such a thing in [git-annex](https://git-annex.branchable.com/),
+for peer-to-peer sharing and syncing of git-annex repositories. On November
+13th, I started building it, using Tor, and I'm releasing it concurrently with
+this blog post.
+
+[[!template id=note text="""
+git-annex's Tor support replaces its old hack of tunneling git
+protocol over XMPP. That hack was unreliable (it needed a TCP on top of XMPP
+layer) but worse, the XMPP server could see all the data being transferred.
+And, there are fewer large XMPP servers these days, so fewer users could
+use it at all. If you were using XMPP with git-annex, you'll need to switch
+to either Tor or a server accessed via ssh.
+"""]]
+
+Now git-annex can serve a repository as a Tor onion service, and that can
+then be accessed as a git remote, using an url like
+`tor-annex::tungqmfb62z3qirc.onion:42913`. All the regular git, and
+git-annex commands, can be used with such a remote.
+
+Tor has a lot of goals for protecting anonymity and privacy. But the
+important things for this project are just that it has end-to-end
+encryption, with addresses that are public keys, and allows P2P
+connections. Building an anonymous file exchange on top of Tor is not my
+goal -- if you want that, you probably don't want to be exchanging git
+histories that record every edit to the file and expose your real name by
+default.
+
+Building this was not without its difficulties.
+Tor onion services were originally intended to run hidden websites,
+not to connect peers to peers, and this kind of shows..
+
+Tor does not cater to end users setting up lots of Onion services.
+Either root has to edit the `torrc` file, or the Tor control port can be
+used to ask it to set one up. But, the control port is not enabled by
+default, so you still need to su to root to enable it. Also, it's difficult
+to find a place to put the hidden service's unix socket file that's
+writable by a non-root user. So I had to code around this, with a `git
+annex enable-tor` that su's to root and sets it all up for you.
+
+[[!template id=note text="""
+One interesting detail about the implementation of the P2P protocol in
+git-annex is that it uses two Free monads to build up actions. There's a Net
+monad which can be used to send and receive protocol messages, and a Local
+monad which allows only the necessary modifications to files on disk.
+Interpreters for Free monad actions can chose exactly which actions to
+allow for security reasons. 
+
+For example, before a peer has authenticated,
+the P2P protocol is being run by an interpreter that refuses to run any
+Local actions whatsoever. Other interpreters for the Net monad could be
+used to support other network transports than Tor.
+"""]]
+
+When when two peers are connected over Tor, one knows it's talking to the
+owner of a particular onion address, but the other peer knows nothing about
+who's talking to it, by design. This makes authentication harder than it
+would be in a P2P system with a design like Telehash. 
+So git-annex does its own authentication on top of Tor.
+
+With authentication, users would need to exchange absurdly long
+addresses (over 150 characters) to connect their repositories. One very
+convenient thing about using XMPP was that a user would have connections to
+their friend's accounts, so it was easy to share with them. Exchanging long
+addresses is too hard.
+
+This is where [Magic Wormhole](https://github.com/warner/magic-wormhole)
+saved the day. It's a very elegant way to get any two peers in touch
+with each other, and the users only have to exchange a short code
+phrase, like "2-mango-delight", which can only be used once. Magic Wormhole
+makes some security tradeoffs for this simplicity. It's got vulnerabilities
+to DOS attacks, and its MITM resistance could be improved. But I'm lucky
+it came along just in time.
+
+So, it takes only installing Tor and Magic Wormhole, 
+running two git-annex commands, and exchanging short code phrases with
+a friend, perhaps over the phone or in an encrypted email, to get
+your git-annex repositories connected and syncing over Tor. 
+[See the documentation](http://git-annex.branchable.com/tips/peer_to_peer_network_with_tor/)
+for details. Also, the git-annex webapp allows
+[setting the same thing up point-and-click style](http://git-annex.branchable.com/assistant/share_with_a_friend_walkthrough/).
+
+The Tor project blog has throughout December been [featuring all kinds of
+projects that are using Tor](https://blog.torproject.org/blog). 
+Consider this a late bonus addition to that. ;) 
+
+I hope that Tor onion services will continue to develop to make them easier
+to use for peer-to-peer systems. We can still dream a better Internet.
+
+----
+
+This work was made possible by all my supporters on
+[Patreon](https://patreon.com/joeyh/).

from email
diff --git a/blog/entry/multi-terminal_applications/comment_7_30aba9e905e58f33db64e52af14c7647._comment b/blog/entry/multi-terminal_applications/comment_7_30aba9e905e58f33db64e52af14c7647._comment
new file mode 100644
index 0000000..531e078
--- /dev/null
+++ b/blog/entry/multi-terminal_applications/comment_7_30aba9e905e58f33db64e52af14c7647._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="anarcat"
+ nickname="anarcat"
+ subject="comment 7"
+ date="2016-12-27T18:02:47Z"
+ content="""
+i have a similar concern in a project i'm working on now, which is to
+run a bunch of tests in one window and showing system logs in another
+window for convenience. i thought i would use tmux for this because the
+commandline interface is simple enough to be used like an API. my
+previous approach to this was to use a multi-interface design with
+simple functions like "alert", "prompt" or "log" that would send stuff
+to different places (terminal or gtk windows) depending on the
+environment, a bit like what debconf is doing, with all the crap that
+implies (generally: a suboptimal interface everywhere).
+
+as for an irc client, you may be curious to try out `ii`: it's a simple
+FIFO and filesystem-based irc client that implements basically *no* user
+interface... a little nuts, but sounds like it would be the backend to
+the UI you are describing.
+"""]]

no more telnet for scroll
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index fa21794..49cdcab 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -14,11 +14,8 @@ BTW, `scroll` is also a functional unix file pager, like `less` or `more`.
 
 For a quick play on the web, there are two demo servers up!
 
-* EU <http://eu.scroll.joeyh.name:4242/>  -or-  `telnet eu.scroll.joeyh.name`
-* US <http://us.scroll.joeyh.name:4242/>  -or-  `telnet us.scroll.joeyh.name`
-
-For deeper exploration, I recommend using telnet instead. Login and
-password for telnet are both "scroll".
+* EU <http://eu.scroll.joeyh.name:4242/>
+* US <http://us.scroll.joeyh.name:4242/>
 
 ## install `scroll`
 

Added a comment: Multi Pty programs
diff --git a/blog/entry/multi-terminal_applications/comment_6_30aba9e905e58f33db64e52af14c7647._comment b/blog/entry/multi-terminal_applications/comment_6_30aba9e905e58f33db64e52af14c7647._comment
new file mode 100644
index 0000000..2e98e3a
--- /dev/null
+++ b/blog/entry/multi-terminal_applications/comment_6_30aba9e905e58f33db64e52af14c7647._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="bburky@f27cd1468e00e320089df57e65bcda8c8afd6d3e"
+ nickname="bburky"
+ avatar="http://cdn.libravatar.org/avatar/e998a8229b9bfe9856d33af99c2f492c"
+ subject="Multi Pty programs"
+ date="2016-12-28T20:48:14Z"
+ content="""
+[Voltron](https://github.com/snare/voltron) is a good example of this kind of program I think. I haven't actually used it, but it's a debugger interface that lets you spwawn new windows by using multiple ptys.
+"""]]

update
diff --git a/blog/entry/multi-terminal_applications/comment_5_cc21cb426b45ba5dd26a405c2fb53df5._comment b/blog/entry/multi-terminal_applications/comment_5_cc21cb426b45ba5dd26a405c2fb53df5._comment
index 337d83a..aa340bd 100644
--- a/blog/entry/multi-terminal_applications/comment_5_cc21cb426b45ba5dd26a405c2fb53df5._comment
+++ b/blog/entry/multi-terminal_applications/comment_5_cc21cb426b45ba5dd26a405c2fb53df5._comment
@@ -27,7 +27,8 @@ xterm with that size, or tile a buffer at that size).
 
 It would probably be a good idea to add a parameter to both API calls for
 additional hints. For example, a pty manager might be able to lay out one
-buffer to the left of an other one, if provided a hint to do so. This
-needs to be something that's extensible. Could be as simple as 
-`char *const managehints[]`
+buffer to the left of an other one, if provided a hint to do so. Or a pty
+might be non-interactive, and so a pty manager should not let the focus
+move to it. This needs to be something that's extensible. Could be as
+simple as  `char *const managehints[]`
 """]]

update
diff --git a/blog/entry/multi-terminal_applications/comment_5_cc21cb426b45ba5dd26a405c2fb53df5._comment b/blog/entry/multi-terminal_applications/comment_5_cc21cb426b45ba5dd26a405c2fb53df5._comment
index a4596a7..337d83a 100644
--- a/blog/entry/multi-terminal_applications/comment_5_cc21cb426b45ba5dd26a405c2fb53df5._comment
+++ b/blog/entry/multi-terminal_applications/comment_5_cc21cb426b45ba5dd26a405c2fb53df5._comment
@@ -11,6 +11,7 @@ The C API could look like this:
 		const struct winsize *winp);
 
 	pid_t execvpepty_managed(const char *addr,
+		const struct winsize *winp,
 		const char *file, char *const argv[], char *const envp[]);
 
 Compare with openpty(3) and forkpty(3).
@@ -20,4 +21,13 @@ and any parent address is automatically prefixed to it.
 
 The implementation of these would use the socket environment variable to
 send requests to the pty manager. Mm, fd passing..
+
+The winsize parameter lets a preferred window size be selected (to open an
+xterm with that size, or tile a buffer at that size).
+
+It would probably be a good idea to add a parameter to both API calls for
+additional hints. For example, a pty manager might be able to lay out one
+buffer to the left of an other one, if provided a hint to do so. This
+needs to be something that's extensible. Could be as simple as 
+`char *const managehints[]`
 """]]

comment
diff --git a/blog/entry/multi-terminal_applications/comment_5_cc21cb426b45ba5dd26a405c2fb53df5._comment b/blog/entry/multi-terminal_applications/comment_5_cc21cb426b45ba5dd26a405c2fb53df5._comment
new file mode 100644
index 0000000..a4596a7
--- /dev/null
+++ b/blog/entry/multi-terminal_applications/comment_5_cc21cb426b45ba5dd26a405c2fb53df5._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 5"""
+ date="2016-12-28T00:17:47Z"
+ content="""
+The C API could look like this:
+
+	int openpty_managed(const char *addr,
+		int *amaster, int *aslave, char *name,
+		const struct termios *termp,
+		const struct winsize *winp);
+
+	pid_t execvpepty_managed(const char *addr,
+		const char *file, char *const argv[], char *const envp[]);
+
+Compare with openpty(3) and forkpty(3).
+
+Here `addr` is the address of the pty, eg "irc-client.channel.#haskell",
+and any parent address is automatically prefixed to it.
+
+The implementation of these would use the socket environment variable to
+send requests to the pty manager. Mm, fd passing..
+"""]]

comment
diff --git a/blog/entry/multi-terminal_applications/comment_3_f9553873da665f964496b7fe9fd5f889._comment b/blog/entry/multi-terminal_applications/comment_3_f9553873da665f964496b7fe9fd5f889._comment
new file mode 100644
index 0000000..98490c0
--- /dev/null
+++ b/blog/entry/multi-terminal_applications/comment_3_f9553873da665f964496b7fe9fd5f889._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2016-12-27T23:23:10Z"
+ content="""
+Trying `st` with my ad-hoc benchmark, it managed to scroll around 4
+thousand lines without noticable flicker. But I don't think `st` has a
+scroll buffer. Running `screen` in it to buffer the scrollback slowed
+it down to around 1-2 thousand lines, so comprable to vte.
+"""]]
diff --git a/blog/entry/multi-terminal_applications/comment_4_ff1585b0d30d05f0f8936bc8fa50a13f._comment b/blog/entry/multi-terminal_applications/comment_4_ff1585b0d30d05f0f8936bc8fa50a13f._comment
new file mode 100644
index 0000000..2c9c5dc
--- /dev/null
+++ b/blog/entry/multi-terminal_applications/comment_4_ff1585b0d30d05f0f8936bc8fa50a13f._comment
@@ -0,0 +1,53 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 4"""
+ date="2016-12-27T23:24:57Z"
+ content="""
+@josh interesting thoughts..
+
+A pty-management library does seem like a good idea. There could be
+different pty-manager commands that open xterms, open screen
+buffers, etc. So the user runs something like:
+
+	in-xterms irc-client
+
+	in-screen irc-client
+
+And irc-client could also be run in any shell that was started inside a
+pty-manager, talking to the outer pty-manager.
+
+When the irc-client opens a pty, in-xterms would need to use something 
+like `xterm -e connect-pty` to open a new xterm connected back to that pty.
+But when the irc-client runs the mail-client, in-xterms can just run 
+`xterm -e mail-client` and doesn't need to relay. 
+
+(Leaving aside for the momemnt the problem that xterm -e does not propigate
+the exit status of the program it runs to its caller..)
+
+While connect-pty would have some copying and syscall overhead
+(probably similar to `screen`), if a program found that excessive, it could
+run a child process, which would be connected up directly to the terminal
+(in the in-xterms case). That also provides a workaround for the singleton
+termnal in curses libraries.
+
+As well as an environment variable containing the socket of the
+pty-manager, there could be one containing the address of the pty. If an
+irc-client opens a new pty to run a mail client, the mail client would see
+an address of eg "irc-client.mail-client", and it can use that address when
+it opens a new pty for an editor, so the editor gets an address of eg
+"irc-client.mail-client.editor". The pty manager can see a whole tree:
+
+	irc-client.channellist
+	irc-client.#haskell
+	irc-client.#haskell.userlist
+	irc-client.mail-client
+	irc-client.mail-client.message.happy new year
+	irc-client.mail-client.editor.file.tmpmsg
+	irc-client.mail-client.editor.help-window
+	irc-client.mail-client.editor.shell
+
+Such human-friendly names in a tree would be useful for
+interactively managing ptys and could also inform tiling layouts.
+It also lets the pty manager set the default window title/screen
+buffer name to something reasonable.
+"""]]

Added a comment
diff --git a/blog/entry/multi-terminal_applications/comment_2_053b5c92c394c8689fbc65e38227fd4b._comment b/blog/entry/multi-terminal_applications/comment_2_053b5c92c394c8689fbc65e38227fd4b._comment
new file mode 100644
index 0000000..3065787
--- /dev/null
+++ b/blog/entry/multi-terminal_applications/comment_2_053b5c92c394c8689fbc65e38227fd4b._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="josh@ccccabe84317e1b7429fd465de0b38fd54925dea"
+ nickname="josh"
+ avatar="http://cdn.libravatar.org/avatar/1bd07f791d8ed5989a92790b0a1f9ea4"
+ subject="comment 2"
+ date="2016-12-27T21:34:50Z"
+ content="""
+I like the idea of unifying terminals, editors, IRC clients, mail clients, and other things that need multiple windows (whether tiled, tabbed, or just switched between).  I don't know that I'd want to use terminal scrollback for that (I prefer editor-style or screen-style buffers with scroll positions), but many aspects of all those programs overlap.  I can see why people use Emacs for everything, and I hope to see vim/neovim go in the same direction now that both have introduced coprocess support.
+
+Editor buffers work nicely as a generalization, but they don't fit perfectly.  For instance, embedding a shell in an editor needs to disable some of the editing functions for part but not all of the buffer.  You want to use the editor to edit the next command line, but treat the prompt before it as read-only.  (But you can use editor functions to search and copy text.)
+
+I'd love to have a \"libtmux\" or \"libscreen\" that applications can embed.  But I'd also like those applications to cooperate within a single thing that behaves like screen/tmux/vim, not to each have their own.  What would such an abstraction look like?
+
+What about a multi-pty-management library that can delegate to an outer multi-pty-management application.  Imagine a library that lets you manage a pile of independent terminal-like buffers, and manage them like screen/tmux within a normal containing terminal.  However, that library can also recognize when run inside an application that can handle such buffers itself (such as via an environment variable providing a communication socket).  In that case, it'll contact that application, and delegate pty management to that application.  The application can then logically group the buffers from each application together, and provide various functions for navigation, tiling, tabbing, switching, scrolling, searching, etc.
+"""]]

Added a comment: Cool, yes, technical limitations
diff --git a/blog/entry/multi-terminal_applications/comment_1_cb80cbb6515065e1d5d10e0af1fb4dc7._comment b/blog/entry/multi-terminal_applications/comment_1_cb80cbb6515065e1d5d10e0af1fb4dc7._comment
new file mode 100644
index 0000000..f09a6cf
--- /dev/null
+++ b/blog/entry/multi-terminal_applications/comment_1_cb80cbb6515065e1d5d10e0af1fb4dc7._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="JasonWoof"
+ avatar="http://cdn.libravatar.org/avatar/26d091a5db7b2fbea266e0a5d853affd"
+ subject="Cool, yes, technical limitations"
+ date="2016-12-27T20:00:40Z"
+ content="""
+Firstly: yes, please :-) I've been using nmh for email lately and I love that I can open up a terminal and find something in my email archive for example, without disturbing the email I'm composing, or my inbox emptying process. Being able to connect multiple terminals is somewhat analogous to opening multiple tabs in the browser to the same webapp.
+
+Second, odd that so many terminal emulaters are so slow. I run st (suckless terminal) and it seems to be able to handle about 100,000 lines of output per second (my notes file a few times over, no escape codes but some unicode) on my 6 year old desktop.
+
+Third, most tiling window managers wreak havoc on existing output in terminals, even if they only resize it vertical dimension of the terminals. Tabbed should work fine though.
+"""]]

blog update
diff --git a/blog/entry/multi-terminal_applications.mdwn b/blog/entry/multi-terminal_applications.mdwn
new file mode 100644
index 0000000..116fd8c
--- /dev/null
+++ b/blog/entry/multi-terminal_applications.mdwn
@@ -0,0 +1,103 @@
+While learning about and configuring weechat this evening, I noticed a lot
+of complexity and unsatisfying tradeoffs related to its UI, its mouse
+support, and its built-in window system. Got to wondering what I'd do
+differently, if I wrote my own IRC client, to avoid those problems.
+
+The first thing I realized is, **it is not a good idea to think about
+writing your own IRC client**. Danger will robinson..
+
+So, let's generalize. This blog post is not about designing an IRC client,
+but about exploring simpler ways that something like an IRC client
+might handle its UI, and perhaps designing something general-purpose that
+could be used by someone else to build an IRC client, or be mashed up with
+an existing IRC client.
+
+What any modern IRC client needs to do is display various channels to the
+user. Maybe more than one channel should be visible at a time in some kind
+of window, but often the user will have lots of available channel and only
+want to see a few of them at a time. So there needs to be an interface for
+picking which channel(s) to display, and if multiple windows are shown, for
+arranging the windows. Often that interface also indicates when there is
+activity on a channel. The most recent messages from the channel are
+displayed. There should be a way to scroll back to see messages that have
+already scrolled by. There needs to be an interface for sending a message
+to a channel. Finally, a list of users in the channel is often desired.
+
+Modern IRC clients implement their own UI for channel display, windowing,
+channel selection, activity notification, scrollback, message entry, and
+user list. Even the IRC clients that run in a terminal include all of that.
+But how much of that do they need to implement, really?
+
+Suppose the user has a tabbed window manager, that can display virtual
+terminals. The terminals can set their title, and can indicate when there
+is activity in the terminal. Then an IRC client could just open a bunch of
+terminals, one per channel. Let the window manager handle channel
+selection, windowing (naturally), and activity notification. 
+
+For scrollback, the IRC client can use the terminal's own scrollback
+buffer, so the terminal's regular scrollback interface can be used. This is
+slightly tricky; can't use the terminal's alternate display, and have to
+handle the UI for the message entry line at the bottom.
+
+That's all the UI an IRC client needs (except for the user list), and most
+of that is already implemented in the window manager and virtual terminal.
+So that's an elegant way to make an IRC client without building much new UI
+at all.
+
+But, unfortunately, most of us don't use tabbed window managers (or tabbed
+terminals). Such an IRC client, in a non-tabbed window manager, would be a
+many-windowed mess. Even in a tabbed window manager, it might be annoying
+to have so many windows for one program.
+
+So we need fewer windows. Let's have one channel list window, and one
+channel display window. There could also be a user list window. And there
+could be a way to open additional, dedicated display windows for channels,
+but that's optional. All of these windows can be seperate virtual
+terminals.
+
+A potential problem: When changing the displayed channel, it needs
+to output a significant number of messages for that channel,
+so that the scrollback buffer gets populated. With a large number of lines,
+that can be too slow to feel snappy. In some tests, scrolling 
+10 thousand lines was noticiably slow, but scrolling 1 thousand lines
+happens fast enough not to be noticiable.
+
+(Terminals should really be faster at scrolling than this, but they're still 
+[writing scrollback to unlinked temp files](http://www.climagic.org/bugreports/libvte-scrollback-written-to-disk.html).. sigh!)
+
+An IRC client that uses multiple cooperating virtual terminals, needs a way to
+start up a new virtual terminal displaying the current channel. It could
+run something like this:
+
+	x-terminal-emulator -e the-irc-client --display-current-channel
+
+That would communicate with the main process via a unix socket to find out
+what to display.
+
+Or, more generally:
+
+	x-terminal-emulator -e connect-pty /dev/pts/9
+
+`connect-pty` would simply connect a pty device to the terminal, relaying
+IO between them. The calling program would allocate the pty and do IO to
+it. This may be too general to be optimal though. For one thing, I think
+that most curses libraries have a singleton terminal baked into them, so it
+might be hard to have a single process control cursors on multiple pty's.
+And, it might be innefficient to feed that 1 thousand lines of scrollback
+through the pty and copy it to the terminal.
+
+Less general than that, but still general enough to not involve writing an
+IRC client, would be a library that handled the irc-client-like channel
+display, with messages scrolling up the terminal (and into the scrollback
+buffer), a input area at the bottom, and perhaps a few other fixed regions
+for status bars and etc.
+
+Oh, I already implemented that! In [[code/concurrent-output]],
+over a year ago: [[a_tiling_region_manager_for_the_console]]
+
+I wonder what other terminal applications could be simplified/improved
+by using multiple terminals? One that comes to mind is mutt, which has
+a folder list, a folder view, and an email view, that all are
+shoehorned, with some complexity, into a single terminal.
+
+[[!tag wishlist]]

add more to haskell feed
diff --git a/blog/entry/PoW_bucket_bloom.mdwn b/blog/entry/PoW_bucket_bloom.mdwn
index 91b91fe..6a87a44 100644
--- a/blog/entry/PoW_bucket_bloom.mdwn
+++ b/blog/entry/PoW_bucket_bloom.mdwn
@@ -99,3 +99,5 @@ from flooding so many requests that legitimate clients are forced to do
 an expensive proof of work and then time out waiting for the server. But
 that's an expensive attack to keep running, and the proof of work can 
 be adjusted to make it increasingly expensive.
+
+[[!tag haskell]]
diff --git a/blog/entry/keysafe_alpha_release.mdwn b/blog/entry/keysafe_alpha_release.mdwn
index c9787ee..4ef5781 100644
--- a/blog/entry/keysafe_alpha_release.mdwn
+++ b/blog/entry/keysafe_alpha_release.mdwn
@@ -31,3 +31,5 @@ quick Haskell interface to the C version of the zxcvbn password strength
 estimation library.
 
 PS: Past 50% of my goal on [Patreon](https://www.patreon.com/joeyh)!
+
+[[!tag haskell]]
diff --git a/blog/entry/twenty_years_of_free_software_--_part_12_propellor.mdwn b/blog/entry/twenty_years_of_free_software_--_part_12_propellor.mdwn
index 399a682..749bcd4 100644
--- a/blog/entry/twenty_years_of_free_software_--_part_12_propellor.mdwn
+++ b/blog/entry/twenty_years_of_free_software_--_part_12_propellor.mdwn
@@ -42,3 +42,5 @@ Propellor's core data types have evolved much more than in any program I
 worked on before. That's exciting!
 
 Next: [[twenty_years_of_free_software_--_part_13_past_and_future]]
+
+[[!tag haskell]]
diff --git a/blog/entry/twenty_years_of_free_software_--_part_13_past_and_future.mdwn b/blog/entry/twenty_years_of_free_software_--_part_13_past_and_future.mdwn
index c411b1f..4fee31f 100644
--- a/blog/entry/twenty_years_of_free_software_--_part_13_past_and_future.mdwn
+++ b/blog/entry/twenty_years_of_free_software_--_part_13_past_and_future.mdwn
@@ -28,3 +28,5 @@ and *wham* got hit by the type theory bus. And now I see that I was stuck
 in a rut before, and begin to get a feeling of many new possibilities.
 
 That's a good feeling to have, twenty years in.
+
+[[!tag haskell]]

oldest first
diff --git a/blog/haskell.mdwn b/blog/haskell.mdwn
index 5fb8f8f..65c767b 100644
--- a/blog/haskell.mdwn
+++ b/blog/haskell.mdwn
@@ -1,4 +1,4 @@
-Haskell-related posts to [[Joey]]'s [[blog]].
+Haskell-related posts to [[Joey]]'s [[blog]], oldest first.
 
 [[!inline pages="blog/entry/* and link(haskell) and !*/Discussion" show=0
 reverse=yes]]

oops
diff --git a/blog/haskell.mdwn b/blog/haskell.mdwn
index 69f6901..5fb8f8f 100644
--- a/blog/haskell.mdwn
+++ b/blog/haskell.mdwn
@@ -1,4 +1,4 @@
 Haskell-related posts to [[Joey]]'s [[blog]].
 
 [[!inline pages="blog/entry/* and link(haskell) and !*/Discussion" show=0
-sort=reverse]]
+reverse=yes]]

reverse this page
diff --git a/blog/haskell.mdwn b/blog/haskell.mdwn
index b48beb1..69f6901 100644
--- a/blog/haskell.mdwn
+++ b/blog/haskell.mdwn
@@ -1,3 +1,4 @@
 Haskell-related posts to [[Joey]]'s [[blog]].
 
-[[!inline pages="blog/entry/* and link(haskell) and !*/Discussion" show=0]]
+[[!inline pages="blog/entry/* and link(haskell) and !*/Discussion" show=0
+sort=reverse]]

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 c412b92..393d216 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 46 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 12 "not interested"]]
+[[!poll 47 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 12 "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 543b3af..c412b92 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 45 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 12 "not interested"]]
+[[!poll 46 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 12 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

keysafe
diff --git a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
index aeb5fce..7a6b2a2 100644
--- a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
+++ b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
@@ -6,3 +6,8 @@ Linux.Conf.Au is a wonderful conference, and I'm thrilled to be able to
 attend it again.
 
 [[!tag propellor]]
+
+--
+
+Update: My presentation on [[code/keysafe]] has also been accepted for the
+Security MiniConf at LCA, January 17th.
diff --git a/code/keysafe/details.mdwn b/code/keysafe/details.mdwn
index 4b18e32..e0f85e5 100644
--- a/code/keysafe/details.mdwn
+++ b/code/keysafe/details.mdwn
@@ -51,7 +51,7 @@ average of 35 minutes.
 * Repeat for next password.
 
 So, for a password with N entropy, the number of CPU-years of work
-is to crack it is: 2^(N-1)*50/60/24/365
+is to crack it is: `2^(N-1)*50/60/24/365`
 
 * Strong password (50 entropy): 53553077761 CPU-years
 * Weak password (30 entropy): 51072 CPU-years
@@ -84,10 +84,10 @@ of shards, and obtain all the encrypted keys for further cracking. So it's
 important that there not be any checksum or header in addition to the AES
 encrypted data. (AES encrypted data cannot be distinguised from random
 garbage except by block size.) Get that right, and with N keysafe users, an
-attacker would need to try 2^(N-1) combinations of shards to find one on
+attacker would need to try `2^(N-1)` combinations of shards to find one on
 average, and would need to brute force the password of each combination.
 With only 20 keysafe users, assuming all users have super-weak passwords,
-this attack takes 13107200 years of CPU work (2^19*25) to crack one. With
+this attack takes 13107200 years of CPU work `(2^19*25)` to crack one. With
 50 users, this jumps to quadrillions of years of CPU work.
 
 Colluding servers can try to correlate related objects based on access

fix identica feed
diff --git a/grep.mdwn b/grep.mdwn
index e73e432..00fe74b 100644
--- a/grep.mdwn
+++ b/grep.mdwn
@@ -8,5 +8,5 @@ on the net.
 List of feeds:
 
 * [[!aggregate expirecount=25 name="music" feedurl="http://libre.fm/rdf.php?fmt=rss&page=%2Fuser%2Fjoeyhess%2Frecent-tracks" url="http://libre.fm/user/joeyhess"]]
-* [[!aggregate expirecount=25 name="identi.ca posts" feedurl="http://tmp.joeyh.name/pump.atom" url="http://identi.ca/joeyh"]]
+* [[!aggregate expirecount=25 name="identi.ca posts" feedurl="https://pump2rss.com/feed/joeyh@identi.ca.atom" url="http://identi.ca/joeyh"]]
 * [[!aggregate expirecount=25 name="books" feedurl="http://www.goodreads.com/review/list_rss/2159448?key=afd7e8432b3f9e33edab442a7c94e95849af4527&shelf=currently-reading" url="http://www.goodreads.com/user/show/2159448"]]

blog update
diff --git a/blog/entry/drought.mdwn b/blog/entry/drought.mdwn
new file mode 100644
index 0000000..6b6b372
--- /dev/null
+++ b/blog/entry/drought.mdwn
@@ -0,0 +1,28 @@
+Drought here since August. The small cistern ran dry a month ago, which has
+never happened before. The large cistern was down to some 900 gallons. I
+don't use anywhere near the national average of 400 gallons per day. More
+like 10 gallons. So could have managed for a few more months.
+Still, this was worrying, especially as the area moved from severe to
+extreme drought according to the 
+[US Drought Monitor](http://droughtmonitor.unl.edu/).
+
+Two days of solid rain fixed it, yay! The small cistern has already
+refilled, and the large will probably be full by tomorrow.
+
+The winds preceeding that same rain storm fanned the flames that
+destroyed Gatlinburg. Earlier, fire got within 10 miles of here,
+although that may have been some kind of controlled burn.
+
+Climate change is leading to longer duration weather events in this area.
+What tended to be a couple of dry weeks in the fall, has become multiple
+months of drought and weeks of fire. What might have been a few days of
+winter weather and a few inches of snow before the front moved through has
+turned into multiple weeks of arctic air, with multiple 1 ft snowfalls.
+What might have been a few scorching summer days has become a week of
+100-110 degree temperatures. I've seen all that over the past several
+years.
+
+After this, I'm adding "additional, larger cistern" to my todo list.
+Also "larger fire break around house".
+
+[[!tag lay]]

add
diff --git a/code.mdwn b/code.mdwn
index 9d6bceb..2aa5ac7 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -50,6 +50,7 @@ people have taken them on.
 [[pentium-builder]]
 [[apt-src]]
 [[jetring]]
+[[scriptreplay]]
 
 These need new maintainers, stat!
 
diff --git a/code/scriptreplay.mdwn b/code/scriptreplay.mdwn
new file mode 100644
index 0000000..874b37e
--- /dev/null
+++ b/code/scriptreplay.mdwn
@@ -0,0 +1,31 @@
+In 2000, I [patched script](https://bugs.debian.org/68556) to
+dump out timing information, which let typescripts be
+replayed with realistic typing and output delays by a
+`scriptreplay` command I whipped up.
+
+This was not a unique idea; Anthony Towns had some code to do
+something similar. And four months later, Satoru Takabayashi
+created [ttyrec](http://0xcc.net/ttyrec/) which does much the same.
+Of screenreplay, he says:
+
+> A friend of mine told me that Mr. Joey Hess implemented the same thing.
+> If I had only known that earlier, I would have never reinvented the
+> wheel...
+
+In the end, ttyrec became the go-to tool for this purpose. Probably
+because it includes all the information in a single file, rather than the
+two files script uses (one for the terminal output and the other
+that I added for the timings)
+
+In any case, it's common now to record terminal sessions and play
+them back in real time. One of the best known uses is by
+[nethack.alt.org](https://nethack.alt.org/) for replay and live
+watching of games.
+
+I've had nothing to do with scriptreplay since I wrote it. Others have
+maintained it since. I tend to use ttyrec more myself,
+and have made a number of improvements to it, some of which have been
+included in the Debian package, but none of which seem to have gotten back
+to upstream as of yet. A number of my other patches to ttyrec, including
+using inotify to improve live playback of ttyrecord, are languishing 
+in a [git repository](https://git.joeyh.name/?p=zzattic/ttyrec.git;a=summary).

desc
diff --git a/index.mdwn b/index.mdwn
index 664493f..fe978e5 100644
--- a/index.mdwn
+++ b/index.mdwn
@@ -1,5 +1,5 @@
 [[!meta title="Joey Hess"]]
-[[!meta description="home page, blog, projects, interviews, and hidden jems"]]
+[[!meta description="building worthwhile things that might last"]]
 
 <div>
 <style>

desc
diff --git a/blog.mdwn b/blog.mdwn
index 89195b3..afef011 100644
--- a/blog.mdwn
+++ b/blog.mdwn
@@ -1,4 +1,5 @@
 [[!meta title="see shy jo"]]
+[[!meta description="Joey Hess's blog"]]
 
 [[!inline pages="blog/entry/* and !blog/entry/*/* and !link(foo) and 
 !link(unfinished)"

desc
diff --git a/index.mdwn b/index.mdwn
index 4cccc7e..664493f 100644
--- a/index.mdwn
+++ b/index.mdwn
@@ -1,4 +1,5 @@
 [[!meta title="Joey Hess"]]
+[[!meta description="home page, blog, projects, interviews, and hidden jems"]]
 
 <div>
 <style>

remove old cruft
diff --git a/joeyca/cacert.crt b/joeyca/cacert.crt
deleted file mode 100644
index aafcd75..0000000
--- a/joeyca/cacert.crt
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC9zCCAmCgAwIBAgIBADANBgkqhkiG9w0BAQQFADBhMQswCQYDVQQGEwJVUzEL
-MAkGA1UECBMCVE4xEDAOBgNVBAoTB2tpdGVuZXQxEjAQBgNVBAMTCUpvZXkgSGVz
-czEfMB0GCSqGSIb3DQEJARYQam9leUBraXRlbmV0Lm5ldDAeFw0wMzA3MjAwODUx
-NTVaFw0xMzA3MTcwODUxNTVaMGExCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJUTjEQ
-MA4GA1UEChMHa2l0ZW5ldDESMBAGA1UEAxMJSm9leSBIZXNzMR8wHQYJKoZIhvcN
-AQkBFhBqb2V5QGtpdGVuZXQubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
-gQC+CdlAO61uyyqHx9XST63R9hk6aPiMXO9mnp3sHrgybpfisXizPx5l3UdGZX8t
-A59K6EjoQd1ClLOoYJdOSxH+yzQfUQ3JNsbKYkzarGEfy/D5PV6mTonzHxdF4sdj
-uGH+Ov2kiU3hxCRGpoqEagi9H+m2T7J32qAFDebqwbUDAQIDAQABo4G+MIG7MB0G
-A1UdDgQWBBQgh36YzCLs2dXfrvYuAhoSXak99zCBiwYDVR0jBIGDMIGAgBQgh36Y
-zCLs2dXfrvYuAhoSXak996FlpGMwYTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlRO
-MRAwDgYDVQQKEwdraXRlbmV0MRIwEAYDVQQDEwlKb2V5IEhlc3MxHzAdBgkqhkiG
-9w0BCQEWEGpvZXlAa2l0ZW5ldC5uZXSCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG
-9w0BAQQFAAOBgQA4BBQUKLlXzRC0DxkbU3FHKNVRb4RvPMFdw3L7NLBR/ZM+7VS0
-5CWCTUfSXmS0mUf/kTpk7z2Mv1Sdca/br+Wm8UB90xVgHlteMri3L+qnvgu39SRO
-Y05VaIDcaDtvbDUg93eQTOkZ1pYxphN3shd0lxInHSNaijQccWokxsDJTw==
------END CERTIFICATE-----
diff --git a/joeyca/cacert.crt.asc b/joeyca/cacert.crt.asc
deleted file mode 100644
index 53a5367..0000000
--- a/joeyca/cacert.crt.asc
+++ /dev/null
@@ -1,24 +0,0 @@
------BEGIN PGP MESSAGE-----
-Version: GnuPG v1.2.2 (GNU/Linux)
-
-owFtVDuP41QUHnahwNIW09CAEMV2EcSJ8xgjrUb3FdtJrjPXr9ih8iOxHTuTd+y4
-X2m1oqBGSGyxULEdNPyAraCgXUo6tCUNHXaGGRbBlW7z6V6d8z3O+eLB/bN7569e
-HX/On14O33rxtuZxvutPN7tP/M3u8sPfn35cHUgkRf0IEc1QegoCBjmhHFUUJBYI
-gQUKQaZAEJYXAxWGyTpKYknMeAgY6wEMI8q2GWIOthiTSNa3zIIMOQoSCTRMgiBF
-FmnlBIMRDFULgqUBm7tVIFn7ic1yMgfsBqcGMleHiZ2EumQVnF+QGYW8hPS1pCue
-gBnpA81h7kJMpybcuLaWeguLHy7aaYDBtJfxGS2AQOcgG2Ez51TDckswP4GGfwIr
-jEokRwXo31R1DJBaxhsUlJKCacwJKym0bihEVHabKT8ZV5WITiE44SCnfb3qRofK
-xFYLql1kMnP6g+VEiQ6+ygGWwF4E117TajPpjvO+apsq0oyCf9ErBTVBWVMFGMGY
-DSAXMlRDQQpGncb+eFzLuWjrRkfQxCjpuFcxtUfi4nolbOVNePRWs3hrx8VV3k4F
-M5Am9sWOA21x0CHzJQsaKB2Olk4/GOm5XDsWbGYyoa9uvYGTFO5GIrNjHbevrM7C
-WF4Xch70Wttgzu0luTY6NJPYFKIcadJquSZuGItybdE0un2huQY9PPXWmWdiwJTy
-ArhsSbWSXrdyjyuFCnDIxhCyMBI6ToGG22ZgzzYHZw+ipW67iVgGDcZZqb7Gz6Ei
-4fIzCP9+z/3vh04vXUk0cwwyvA1amUNkWfQNa8PSWm3EUQ1kODx5OyBZcBccqikZ
-AScckywdVC4pJEp9geZyAYLbqHNV1hEjYyJV8UzBXRZQu7RTRyXnDINT+wYEZgYy
-AuvFP7PC3Q1LNQIMtEotzMEwtQsN8ThPPFPoyQPV0ryWdriivSAThl11CLX6hNa6
-ls5zbTRGhjnT7YXOL8xZPTFWSbdo0kNDD3y37m1q48WFCUU+t0I53U3pJhaGtfX1
-IdwLol5q4PBty1Ww7+LdwcNmKApTZoySSWPl5KtIFbZRwKe5ci3rqhvPme+Pl0m+
-xX0je/SIO20EouL/boknl/ffOatWye2aOb9Ht2fPvnrv+0ny3Qfffvb6z8ZPD9/9
-8cX5H1+fPfvmy5fnn//6Ev7y+FP1wfPf3v/h9XP9Lw==
-=C4IM
------END PGP MESSAGE-----
diff --git a/joeyca/gpgkey.asc b/joeyca/gpgkey.asc
deleted file mode 100644
index 4d00577..0000000
--- a/joeyca/gpgkey.asc
+++ /dev/null
@@ -1,1373 +0,0 @@
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.0.7 (GNU/Linux)
-
-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

(Diff truncated)
add news item for github-backup 1.20161118
diff --git a/code/github-backup/news/version_1.20160319.mdwn b/code/github-backup/news/version_1.20160319.mdwn
deleted file mode 100644
index ca3efaf..0000000
--- a/code/github-backup/news/version_1.20160319.mdwn
+++ /dev/null
@@ -1,6 +0,0 @@
-github-backup 1.20160319 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Update to github-0.14.1.
-     Building with old versions is not supported due to the massive API
-     changes in this version of the github library.
-   * Added support for oath tokens."""]]
\ No newline at end of file
diff --git a/code/github-backup/news/version_1.20161118.mdwn b/code/github-backup/news/version_1.20161118.mdwn
new file mode 100644
index 0000000..81a7226
--- /dev/null
+++ b/code/github-backup/news/version_1.20161118.mdwn
@@ -0,0 +1,3 @@
+github-backup 1.20161118 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix build with recent versions of cabal."""]]
\ No newline at end of file

fix
diff --git a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
index 2936627..aeb5fce 100644
--- a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
+++ b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
@@ -5,4 +5,4 @@ Hobart, Tasmania. [Abstract](https://linux.conf.au/schedule/presentation/116/)
 Linux.Conf.Au is a wonderful conference, and I'm thrilled to be able to
 attend it again.
 
-[[!tag code/propellor]]
+[[!tag propellor]]

fix
diff --git a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
index fe490d8..2936627 100644
--- a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
+++ b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
@@ -5,4 +5,4 @@ Hobart, Tasmania. [Abstract](https://linux.conf.au/schedule/presentation/116/)
 Linux.Conf.Au is a wonderful conference, and I'm thrilled to be able to
 attend it again.
 
-[[!code/propellor]]
+[[!tag code/propellor]]

blog update
diff --git a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
new file mode 100644
index 0000000..fe490d8
--- /dev/null
+++ b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
@@ -0,0 +1,8 @@
+On January 18th, I'll be presenting 
+"Type driven configuration management with Propellor" at Linux.Conf.Au in
+Hobart, Tasmania. [Abstract](https://linux.conf.au/schedule/presentation/116/)
+
+Linux.Conf.Au is a wonderful conference, and I'm thrilled to be able to
+attend it again.
+
+[[!code/propellor]]

add news item for github-backup 1.20161110
diff --git a/code/github-backup/news/version_1.20160207.mdwn b/code/github-backup/news/version_1.20160207.mdwn
deleted file mode 100644
index 2d7fd4e..0000000
--- a/code/github-backup/news/version_1.20160207.mdwn
+++ /dev/null
@@ -1,10 +0,0 @@
-github-backup 1.20160207 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Switch to using https instead of git:// for a secure transport.
-     Note that existing git:// remotes will continue to be used.
-     Thanks, Robin Schneider.
-   * Add upper bound on github dependency, as version 0.14 has large API
-     changes and can't be used yet.
-   * Various updates to internal git and utility libraries shared
-     with git-annex.
-   * Silence build warnings with ghc 7.10."""]]
\ No newline at end of file
diff --git a/code/github-backup/news/version_1.20161110.mdwn b/code/github-backup/news/version_1.20161110.mdwn
new file mode 100644
index 0000000..e736fdd
--- /dev/null
+++ b/code/github-backup/news/version_1.20161110.mdwn
@@ -0,0 +1,6 @@
+github-backup 1.20161110 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix build with recent versions of the directory package.
+     Thanks, James McCoy.
+   * Various updates to internal git and utility libraries shared
+     with git-annex."""]]
\ No newline at end of file

add news item for keysafe 0.20161107
diff --git a/code/keysafe/news/version_0.20160922.mdwn b/code/keysafe/news/version_0.20160922.mdwn
deleted file mode 100644
index 0cf5ac8..0000000
--- a/code/keysafe/news/version_0.20160922.mdwn
+++ /dev/null
@@ -1,17 +0,0 @@
-keysafe 0.20160922 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Keysafe now knows about 3 servers, although only 1 is currently in
-     operation. It will queue uploads to the other 2 servers until
-     they are added in a later keysafe release.
-   * Added --autostart mode, and make both keysafe --backup and
-     the Makefile install a FDO desktop autostart file to use it.
-   * In --autostart mode, retry any queued uploads.
-   * In --autostart mode, check for gpg keys that have not been
-     backed up, and offer to back them up. Only ask once per key.
-   * Changed format of ~/.keysafe/backup.log
-   * Server: Reduce number of buckets in rate limiter, avoiding ones with very low
-     proof of work.
-   * Server: Make rate limiter adapt to ongoing load more quickly -- every 15
-     minutes instead of every 60.
-   * Server: Added --backup-server and --restore-server to aid in backing
-     up keysafe servers with minimal information leakage."""]]
\ No newline at end of file
diff --git a/code/keysafe/news/version_0.20161107.mdwn b/code/keysafe/news/version_0.20161107.mdwn
new file mode 100644
index 0000000..d98987e
--- /dev/null
+++ b/code/keysafe/news/version_0.20161107.mdwn
@@ -0,0 +1,14 @@
+keysafe 0.20161107 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * The third keysafe server is now available, provided by Purism.
+   * Purism's keysafe server has been vetted to Recommended level!
+   * Change default for --port to 4242.
+   * Fix --check-server to not fail when the server has not had anything
+     stored on it yet.
+   * --upload-queued: Exit nonzero if unable to upload all queued objects.
+   * --autostart: If unable to upload all queued objects initially,
+     delay between 1 and 2 hours and try again.
+   * Better suggestion when user is having difficulty thinking of a strong
+     enough password.
+   * Defer requesting secret key from gpg until just before backup, so the
+     user knows why gpg is asking for this secret key to be backed up."""]]
\ No newline at end of file

update
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 72b16d3..c1553c7 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -38,7 +38,39 @@ Keysafe's server list puts servers in three categories:
 
 ### Recommended
 
-**None yet!**
+* hlmjmeth356s5ekm.onion
+
+<pre>
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+The keysafe server hlmjmeth356s5ekm.onion is provided and administered by
+Purism. It is located in the EU (Cyprus).
+
+We intend to run this server for at least 10 years (through 2027),
+or failing that, to transition any data stored on it to another
+server that is of similar or higher security.
+
+Our warrant canary is <https://puri.sm/warrant-canary/>,
+and is updated quarterly.
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1
+
+iQIcBAEBAgAGBQJYF8U4AAoJECPPLj0lRRT30CkP/Rn2TAeriNWO9wZcr0OHyX7B
+TJcgLy3pZXbGn6T6qmJqg3K22fTKJ7CX0dfIM+WLI9FfBtnT95q1rnzywhBGPXzj
+eD3g7r3QinIfMLBQTKyc9Ik5132uenD5h72ggVl3D+kuWv622IhaAaiVkuHc5KoR
+3/S+ImkcS/gz83UNTXnWdMs0V8+eqAjpWeYQS8Ih28AECI9f+xUUH//V9Ii/4Usv
+E3Y0hbqj8kSi4/Q6IwmFiJTKZ1FpccKhl6GIYUSLwJMJDHoI46M/AaZy0Xx9pLcU
+niSELai/7/0fY4N0TY2CbZUgH7FEhi0k8cCsGF7yTA6dqya8deKQKdUdDllcHayv
++GOAqijiSTPrRox4TPMMdurPXTsJxeJuxVdS75Lw2cFk+JaaIVS/3XEyeuGpaVKW
+wSTltyFkMx9ur5cCPT2rxoRN78HuqgiHda/Jd4c2pny7GwpUEYAznQQaBYEl2jlQ
+/Go3ZudpnWfBRRe7znazhA6mIatPY61GrNIebVlET6/NCw9sZFRjHXY3pMw1u/TY
+4eP0UQpBUed4/sot5vsZVwbn8e6eFh0S4HTdl5x1G8jN8nUZVdJJjOtACrONW+TG
+CLSNDkMgQ5slBmtZm+MzL2VYkFHCMmPerNXY1DhHjMyfLpQEIN+bho+mIyc5h/W/
+Br5jFZujcQ0u7GzqvaDB
+=RmK4
+-----END PGP SIGNATURE-----
+</pre>
 
 ### Alternate
 
@@ -75,11 +107,6 @@ lhmhvShr0WRqB8fWYPkc
 -----END PGP SIGNATURE-----
 </pre>
 
-* keysafe.puri.sm
-
-  Provided by [Purism](https://puri.sm/). Located in Cyprus.  
-  Vetting to Recommended level in progress.
-
 * thirdserver
 
   Provided by Marek Isalski at [Faelix](http://www.faelix.net/).

add rest of keysafe servers
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 334df3b..72b16d3 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -75,6 +75,17 @@ lhmhvShr0WRqB8fWYPkc
 -----END PGP SIGNATURE-----
 </pre>
 
+* keysafe.puri.sm
+
+  Provided by [Purism](https://puri.sm/). Located in Cyprus.  
+  Vetting to Recommended level in progress.
+
+* thirdserver
+
+  Provided by Marek Isalski at [Faelix](http://www.faelix.net/).
+  Currently located in UK, but planned move to CH.  
+  Vetting to Recommended level in progress.
+
 ## Detailed requirements
 
 ### Alternate

Added a comment
diff --git a/blog/entry/a_rope_ladder_to_the_dgit_treehouse/comment_2_0b2d59f84b135405e0fcd379da7bd032._comment b/blog/entry/a_rope_ladder_to_the_dgit_treehouse/comment_2_0b2d59f84b135405e0fcd379da7bd032._comment
new file mode 100644
index 0000000..12d39cb
--- /dev/null
+++ b/blog/entry/a_rope_ladder_to_the_dgit_treehouse/comment_2_0b2d59f84b135405e0fcd379da7bd032._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ avatar="http://cdn.libravatar.org/avatar/9c3f08f80e67733fd506c353239569eb"
+ subject="comment 2"
+ date="2016-10-24T14:34:38Z"
+ content="""
+The latest release of dgit, 2.7, includes `dgit-maint-merge(7)`, a tutorial building on the ideas in this blog post.
+"""]]

add news item for keysafe 0.20161022
diff --git a/code/keysafe/news/version_0.20160914.mdwn b/code/keysafe/news/version_0.20160914.mdwn
deleted file mode 100644
index 9b0dcd1..0000000
--- a/code/keysafe/news/version_0.20160914.mdwn
+++ /dev/null
@@ -1,21 +0,0 @@
-keysafe 0.20160914 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Fix bug that prevented keysafe --server from running when there was no
-     controlling terminal and zenity was not installed.
-   * Added --name and --othername options.
-   * Added proof of work to client/server protocol.
-   * Server-side rate limiting and DOS protection.
-   * server: Added --months-to-fill-half-disk option, defaulting to 12.
-   * Several new dependencies.
-   * Another fix to gpg secret key list parser.
-   * Warn when uploads fail and are put in the upload queue.
-   * Warn when --uploadqueued fails to upload to servers.
-   * Fix --uploadqueued bug that prevented deletion of local queued file.
-   * Added --chaff mode which uploads random junk to servers.
-     This is useful both to test the server throttling of uploads,
-     and to make it harder for servers to know if an object actually
-     contains secret key information.
-   * Store information about backed up keys in ~/.keysafe/backup.log
-     This can be deleted by the user at any time, but it's useful
-     in case a server is known to be compromised, or a problem is found
-     with keysafe's implementation that makes a backup insecure."""]]
\ No newline at end of file
diff --git a/code/keysafe/news/version_0.20161022.mdwn b/code/keysafe/news/version_0.20161022.mdwn
new file mode 100644
index 0000000..e54f26e
--- /dev/null
+++ b/code/keysafe/news/version_0.20161022.mdwn
@@ -0,0 +1,12 @@
+keysafe 0.20161022 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Add keywords to desktop file.
+     Thanks, Sean Whitton
+   * Fix use of .IP macro in manpage.
+     Thanks, Sean Whitton
+   * Fix some mispellings.
+     Thanks, Sean Whitton
+   * Makefile: Propagate LDFLAGS, CFLAGS, and CPPFLAGS through ghc.
+   * Makefile: Allow setting BUILDER=./Setup to build w/o cabal or stack.
+   * Makefile: Allow setting BUILDEROPTIONS=-j1 to avoid concurrent
+     build, which should make build reproducible."""]]
\ No newline at end of file

add news item for keysafe 0.20161007
diff --git a/code/keysafe/news/version_0.20160831.mdwn b/code/keysafe/news/version_0.20160831.mdwn
deleted file mode 100644
index 7331f21..0000000
--- a/code/keysafe/news/version_0.20160831.mdwn
+++ /dev/null
@@ -1,16 +0,0 @@
-keysafe 0.20160831 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Server implementation is ready for initial deployment.
-   * Keysafe as a client is not yet ready for production use.
-   * Removed embedded copy of secret-sharing library, since finite-field
-     only supports prime fields. This caused shares to be twice the size of
-     the input value.
-   * Reduced chunk size to 32kb due to share size doubling.
-   * Fix gpg secret key list parser to support gpg 2.
-   * Tuned argon2 hash parameters on better hardware than my fanless laptop.
-   * Improve time estimates, taking into account the number of cores.
-   * Added basic test suite.
-   * Added options: --store-directory --test --port --address
-   * Added a Makefile
-   * Added a systemd service file.
-   * Added a desktop file."""]]
\ No newline at end of file
diff --git a/code/keysafe/news/version_0.20161007.mdwn b/code/keysafe/news/version_0.20161007.mdwn
new file mode 100644
index 0000000..a7e8468
--- /dev/null
+++ b/code/keysafe/news/version_0.20161007.mdwn
@@ -0,0 +1,9 @@
+keysafe 0.20161007 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Check if --store-local directory is writable.
+   * Removed dependency on crypto-random.
+   * Added a LSB init script, for non-systemd systems.
+     (It currently uses Debian's start-stop-daemon, so would need porting
+     for other distributions.)
+   * /etc/default/keysafe is read by both the systemd service file and the
+     init script, and contains configuration for the keysafe server."""]]
\ No newline at end of file

new alien maintainer
diff --git a/code.mdwn b/code.mdwn
index 2bd4dc0..9d6bceb 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -38,6 +38,7 @@ people have taken them on.
 [[Debian]]
 [[debian-installer]]
 [[debhelper]]
+[[alien]]
 [[tasksel]]
 [[flashybrid]]
 [[wmbattery]]
@@ -54,7 +55,6 @@ These need new maintainers, stat!
 
 [[debmirror]]
 [[sleepd]]
-[[alien]]
 [[nslu2-utils]]
 [[ticker]]
 
diff --git a/code/alien.mdwn b/code/alien.mdwn
index de043f5..b3c4fad 100644
--- a/code/alien.mdwn
+++ b/code/alien.mdwn
@@ -3,47 +3,17 @@ slackware tgz  file formats. If you want to use a package from another
 distribution than the one you have installed on your system, you can use
 alien to convert it to your preferred package format and install it.
 
-Despite the large version number, alien is still (and will probably always
-be) rather experimental software. It has been used by many people for many
-years, but there are still many bugs and limitations.
-
-Alien should *not* be used to replace important system packages, like 
-sysvinit, shared libraries, or other things that are essential for the 
-functioning of your system. Many of these packages are set up differently by 
-Debian and Red Hat, and packages from the different distributions cannot be 
-used interchangably. In general, if you can't uninstall the package without
-breaking your system, don't try to replace it with an alien version.
-
 ## News
 
 [[!inline pages="code/alien/news/* and !*/Discussion" show="2"]]
 
 ## Downloading alien
 
-Alien is available as the `alien` package in Debian.
-
-Currently the best place to download the tarball is from
-<http://packages.debian.org/unstable/source/alien>
-
-Its git repository is `git://git.joeyh.name/alien`
-
-## Other things you'll need
-
-To use alien, you will need several other programs. Alien is a perl program,
-and requires perl version 5.004 or greater.
-
-To convert packages to or from rpms, you need the Red Hat Package Manager; 
-get it from [its website](http://www.rpm.org/).
-
-If you want to convert packages into debian packages, you will need the 
-dpkg, dpkg-dev, and debhelper packages, which are available on the [Debian packages site](http://packages.debian.org/).
-You'll also need gcc, and make.
+Alien's website has moved to
+<https://sourceforge.net/projects/alien-pkg-convert/>
 
-Attention, all linux users who don't use Debian:
-<a href="mailto:BABCOCK@MATH.PSU.EDU">Bruce S. Babcock</a> has put together a
-package of all the extra files you need to use alien on a non-Debian
-distribution. It's called "alien-extra", and you can download it from
-[his ftp site](ftp://ykbsb2.yk.psu.edu/pub/alien/).
+My old git repository for alien is still available at
+`git://git.joeyh.name/zzattic/alien`
 
 ----
 
diff --git a/code/alien/news/new_alien_maintainer.mdwn b/code/alien/news/new_alien_maintainer.mdwn
new file mode 100644
index 0000000..8f07460
--- /dev/null
+++ b/code/alien/news/new_alien_maintainer.mdwn
@@ -0,0 +1,5 @@
+Kyle Barry has taken over maintenance of alien.
+His versions are available from
+<https://sourceforge.net/projects/alien-pkg-convert/>
+
+This rss feed won't be updated for any new releases of alien.
diff --git a/code/alien/news/version_8.88.mdwn b/code/alien/news/version_8.88.mdwn
deleted file mode 100644
index 99c1cb8..0000000
--- a/code/alien/news/version_8.88.mdwn
+++ /dev/null
@@ -1,4 +0,0 @@
-alien 8.88 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Ensure that version numbers begin with well, a number, when building a
-     deb, otherwise dpkg-deb will refuse to build it."""]]
\ No newline at end of file
diff --git a/code/alien/news/version_8.90.mdwn b/code/alien/news/version_8.90.mdwn
deleted file mode 100644
index 04f4a5c..0000000
--- a/code/alien/news/version_8.90.mdwn
+++ /dev/null
@@ -1,6 +0,0 @@
-alien 8.90 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Add --target=&lt;arch&gt; option for setting architecture. Closes: #[260948](http://bugs.debian.org/260948)
-     (Thanks, Teemu Ikonen)
-   * Add conversion from ppc64le (rpm) to ppc64el (deb).
-   * debhelper v9"""]]
\ No newline at end of file
diff --git a/code/alien/news/version_8.91.mdwn b/code/alien/news/version_8.91.mdwn
deleted file mode 100644
index cadb314..0000000
--- a/code/alien/news/version_8.91.mdwn
+++ /dev/null
@@ -1,5 +0,0 @@
-alien 8.91 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Support other deb data.tar compression schemes in fallback code.
-     Closes: #[718364](http://bugs.debian.org/718364)
-     Thanks, Guillem Jover"""]]
\ No newline at end of file
diff --git a/code/alien/news/version_8.92.mdwn b/code/alien/news/version_8.92.mdwn
deleted file mode 100644
index fc8a3c1..0000000
--- a/code/alien/news/version_8.92.mdwn
+++ /dev/null
@@ -1,4 +0,0 @@
-alien 8.92 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Remove suggests for lsb-rpm, which no longer exists.
-     Closes: #[756873](http://bugs.debian.org/756873)"""]]
\ No newline at end of file
diff --git a/code/alien/news/version_8.93.mdwn b/code/alien/news/version_8.93.mdwn
deleted file mode 100644
index afdb329..0000000
--- a/code/alien/news/version_8.93.mdwn
+++ /dev/null
@@ -1,3 +0,0 @@
-alien 8.93 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Alien needs a new maintainer, both in Debian and upstream."""]]
\ No newline at end of file

Suggest removing parallel
diff --git a/code/moreutils/discussion.mdwn b/code/moreutils/discussion.mdwn
index c6766eb..4cca48f 100644
--- a/code/moreutils/discussion.mdwn
+++ b/code/moreutils/discussion.mdwn
@@ -434,6 +434,8 @@ It would be great if sponge had this same feature as an option: only create the
 
 ## parallel
 
+According to ckester's comment, should we remove parallel from moreutils? The main website of moreutils says: "I'm always interested to add more to the collection, as long as they're suitably general-purpose, and don't DUPLICATE other well-known tools." -- hong
+
 Need to resolve the name conflict with GNU parallel (http://www.gnu.org/software/parallel/).  As far as I can tell, these are two distinct implementations addressing the same general problem space. --ckester
 
 ##### PATCH: make -i and -n not mutually exclusive in parallel

blog update
diff --git a/blog/entry/keysafe_with_local_shares.mdwn b/blog/entry/keysafe_with_local_shares.mdwn
new file mode 100644
index 0000000..1e2c57b
--- /dev/null
+++ b/blog/entry/keysafe_with_local_shares.mdwn
@@ -0,0 +1,56 @@
+If your gpg key is too valuable for you to feel comfortable with
+backing it up to the cloud using [[code/keysafe]], here's an alternative
+that might appeal more. 
+
+Keysafe can now back up some shares of the key to local media, and other
+shares to the cloud. You can arrange things so that the key can't be 
+restored without access to some of the local media and some of the cloud
+servers, as well as your password.
+
+For example, I have 3 USB sticks, and there are 3 keysafe servers. So let's
+make 6 shares total of my gpg secret key and require any 4 of them to
+restore it.
+
+I plug in all 3 USB sticks and look at `mount` to get the paths to them.
+Then, run keysafe, to back up the key spread amoung all 6 locations.
+
+	keysafe --backup --totalshares 6 --neededshares 4 \
+		--add-storage-directory /media/sdc1 \
+		--add-storage-directory /media/sdd1 \
+		--add-storage-directory /media/sde1
+
+Once it's done, I can remove the USB sticks, and distribute them to secure
+places.
+
+To restore, I need at least one of the USB sticks.
+(If some of the servers are down, more USB sticks will be needed.) 
+Again I tell keysafe the paths where USB stick(s) are mounted.
+
+	keysafe --restore --totalshares 6 --neededshares 4 \
+		--add-storage-directory /media/sdb1
+
+Using keysafe this way, physical access to the USB sticks is the first
+level of defense, and hopefully you'll know if that's breached. The keysafe
+password is the second level of defense, and cracking that will take a lot
+of work. Leaving plenty of time to revoke your key, etc, if it comes to
+that.
+
+I feel this is better than the methods I've been using before to back up my
+most important gpg keys. With paperkey, physical access to the printout
+immediately exposes the key. With Shamir Secret Sharing and manual
+distribution of shares, the only second line of defense is the much easier
+to crack gpg passphrase. Using OpenPGP smartcards is still a more secure
+option, but you'd need 3 smartcards to reach the same level of redundancy,
+and it's easier to get your hands on 3 USB sticks than 3 smartcards.
+
+There's another benefit to using keysafe this way. It means that sometimes,
+the data stored on the keysafe servers is not sufficient to crack a key.
+There's no way to tell, so an attacker risks doing a lot of futile work.
+
+If you're not using an OpenPGP smartcard, I encourage you to back up your
+gpg key with keysafe as described above. 
+
+Two of the three necessary keysafe servers are now in operation, and I hope
+to have a full complement of servers soon.
+
+(This was sponsored by Thomas Hochstein on [Patreon](https://patreon.com/joeyh).)

add news item for keysafe 0.20161006
diff --git a/code/keysafe/news/version_0.20160819.mdwn b/code/keysafe/news/version_0.20160819.mdwn
deleted file mode 100644
index 1fe832a..0000000
--- a/code/keysafe/news/version_0.20160819.mdwn
+++ /dev/null
@@ -1,11 +0,0 @@
-keysafe 0.20160819 released
-
-   * First release of keysafe. This is not yet ready for production use.
-   * Network support is not yet implemented, but --store-local works for
-     testing with local data storage.
-   * Data backed up with keysafe version 0.* will not be able to be restored
-     by any later version! Once the data format stabalizes, keysafe version
-     1 data will be supported by every later version.
-   * Argon2 hashes are not yet tuned for modern hardware, but only for my
-     laptop. So, cracking cost estimates may be low. To help with this
-     tuning, run `keysafe --bechmark` and send the output to me.
diff --git a/code/keysafe/news/version_0.20161006.mdwn b/code/keysafe/news/version_0.20161006.mdwn
new file mode 100644
index 0000000..2758b34
--- /dev/null
+++ b/code/keysafe/news/version_0.20161006.mdwn
@@ -0,0 +1,10 @@
+keysafe 0.20161006 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * New --add-storage-directory and --add-server options, which can be used
+     to make keysafe backup/restore using additional locations.
+   * Removed --store-local option; use --add-storage-directory instead.
+   * Fix bugs with entry of gpg keyid in the keysafe.log.
+   * Fix bug in --autostart that caused the full gpg keyid to be
+     used to generate object names, which made restores would only work
+     when --gpgkeyid was specifid.
+   * Remove embedded copy of argon2 binding, depend on fixed version of package."""]]
\ No newline at end of file

Added a comment: remove old batteries?
diff --git a/blog/entry/battery_bank_refresh/comment_2_7d3dcf77d3454c97f849af25636ee5df._comment b/blog/entry/battery_bank_refresh/comment_2_7d3dcf77d3454c97f849af25636ee5df._comment
new file mode 100644
index 0000000..8cbc74f
--- /dev/null
+++ b/blog/entry/battery_bank_refresh/comment_2_7d3dcf77d3454c97f849af25636ee5df._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://anarc.at/openid/"
+ nickname="anarcat"
+ subject="remove old batteries?"
+ date="2016-10-06T12:17:20Z"
+ content="""
+i am not an expert in the field, but it seems to me damaged / discharged batteries may actually be a liability. If you discharge a lead-acid battery too much, it gets damaged and charging it can't quite bring it back to its original capacity, as the terminals get full of crap. \"Too much\" varies from one battery to the other, but 11.1V is *definitely* too low, especially for a battery bank, where that voltage is more an average than the lowest charge point (which means some batteries are *lower* than 11V!).
+
+The worst about damaged batteries in a battery bank is that they bring down other batteries too: the stronger batteries will try to charge the weaker batteries and discharge faster.
+
+Another way to think about this is that every battery is also a resistance as well, even more so when it is damaged.
+
+I can't explain, however, why the two new 12V batteries wouldn't be enough to power the house, unless you have too much of a power drain - I don't know the exact setup here (how much wattage is hooked to the circuit and the exact capacity of the individual batteries) so I can't guess much...
+
+I hope that helps!
+"""]]

Added a comment: Battery bank wiring
diff --git a/blog/entry/battery_bank_refresh/comment_1_6e226a6849a21c3aa53ba2f29ada3c2d._comment b/blog/entry/battery_bank_refresh/comment_1_6e226a6849a21c3aa53ba2f29ada3c2d._comment
new file mode 100644
index 0000000..e910d4b
--- /dev/null
+++ b/blog/entry/battery_bank_refresh/comment_1_6e226a6849a21c3aa53ba2f29ada3c2d._comment
@@ -0,0 +1,32 @@
+[[!comment format=mdwn
+ username="jonatan@f5980658491f77bc917fbe2da469517bd38a9598"
+ nickname="jonatan"
+ subject="Battery bank wiring"
+ date="2016-10-06T09:21:05Z"
+ content="""
+A few recommendations from what I see there, the simplest change I would do to improve the (dis)charging of the batteries would be move one cable to the other side of the bank, like this:
+
+    +---- house 
+    |           
+    +( 6v )-+( 6v )-
+    |              |
+    +( 6v )-+( 6v )-
+    |              |
+    +( 6v )-+( 6v )-
+    |              |
+    +( 6v )-+( 6v )-
+    |              |
+    +( 6v )-+( 6v )-
+    |              |
+    +(   new 12v  )-
+    |              |
+    +(   new 12v  )-
+                   -
+           house----
+
+That way the batteries \"further away\" will also get a decent charge. A good exercise is to calculate the wire length from plus to minus for all batteries. The topology above is not ideal, but usually quite enough. You should take care mixing old and new batteries, if you have a current clamp you can try monitoring the charging and see that all batteries are being utilized and no battery is being over charged.
+
+Check with a voltmeter that the 6V packs are balanced by measuring the midpoints. A temporary solution that can help if they are not is connecting all the midpoints with a thin (like 2 mm^2 or so) cable and letting them settle. If this doesn't help you may need to swap the pairs around to get them better matched
+
+Just a few suggestions to get started, hope it helps!
+"""]]

comment
diff --git a/blog/entry/battery_bank_refresh.mdwn b/blog/entry/battery_bank_refresh.mdwn
index 2d6af76..0ae1c3b 100644
--- a/blog/entry/battery_bank_refresh.mdwn
+++ b/blog/entry/battery_bank_refresh.mdwn
@@ -11,7 +11,7 @@ have a couple of good batteries amoung a dozen failing ones.
 The bank was set up like this:
 
 	+---- house ----
-        |              |
+	|              |
 	+( 6v )-+( 6v )-
 	|              |
 	+( 6v )-+( 6v )-
@@ -35,7 +35,7 @@ On a hunch, I then reconnected one bridge, like this -- and power was
 restored.
 
 	+---- house ----
-        |              |
+	|              |
 	+( 6v )-+( 6v )-
 	|              |
 	+( 6v )  ( 6v )-

blog
diff --git a/blog/entry/battery_bank_refresh.mdwn b/blog/entry/battery_bank_refresh.mdwn
new file mode 100644
index 0000000..2d6af76
--- /dev/null
+++ b/blog/entry/battery_bank_refresh.mdwn
@@ -0,0 +1,72 @@
+My house entered full power saving mode with fall. 
+Lantern light and all devices shutdown at bedtime.
+
+But, it felt early to need to do this. Comparing with my logbook for last
+year, the batteries were indeed doing much worse.
+
+I had added a couple of new batteries to the bank last winter, and they
+seemed to have helped at the time, although it's difficult to tell when you
+have a couple of good batteries amoung a dozen failing ones. 
+
+The bank was set up like this:
+
+	+---- house ----
+        |              |
+	+( 6v )-+( 6v )-
+	|              |
+	+( 6v )-+( 6v )-
+	|              |
+	+( 6v )-+( 6v )-
+	|              |
+	+( 6v )-+( 6v )-
+	|              |
+	+( 6v )-+( 6v )-
+	|              |
+	+(   new 12v  )-
+	|              |
+	+(   new 12v  )-
+
+Tried as an experiement disconnecting all the bridges between the old 6v
+battery pairs. I expected this would mean only the new 12v ones would be in
+the circuit, and so I could see how well they powered the house. Instead,
+making this change left the house without any power at all!
+
+On a hunch, I then reconnected one bridge, like this -- and power was
+restored.
+
+	+---- house ----
+        |              |
+	+( 6v )-+( 6v )-
+	|              |
+	+( 6v )  ( 6v )-
+	|              |
+	+( 6v )  ( 6v )-
+	|              |
+	+( 6v )  ( 6v )-
+	|              |
+	+( 6v )  ( 6v )-
+	|              |
+	+(   new 12v  )-
+	|              |
+	+(   new 12v  )-
+
+My best guess of what's going on is that the wires forming
+the positive and negative rails are not making good connections (due to
+corrosion, rust, broken wires etc), and so batteries further down are
+providing less and less power. The new 12v ones may not have been able
+to push power up to the house at all.
+
+(Or, perhaps having partially dead batteries hanging half-connected off the
+circuit has some effect that my meager electronics knowledge can't account
+for.)
+
+So got longer cables to connect the new batteries directly to the
+house, bypassing all the old stuff. That's working great -- house power
+never dropped below 11.9v last night, vs 11.1v the night before.
+
+The old battery bank might still be able to provide another day or so of
+power in a pinch, so I am going to keep them in there for now, but if
+I don't use them at all this winter I'll be recycling them. Astounding
+that those batteries were in use for [[20_years|getting_to_know_my_batteries]].
+
+[[!tag solar]]

add news item for keysafe 0.20160927
diff --git a/code/keysafe/news/version_0.20160927.mdwn b/code/keysafe/news/version_0.20160927.mdwn
new file mode 100644
index 0000000..1787aa5
--- /dev/null
+++ b/code/keysafe/news/version_0.20160927.mdwn
@@ -0,0 +1,20 @@
+keysafe 0.20160927 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Makefile: Avoid rebuilding on make install, so that sudo make install works.
+   * Added --chaff-max-delay option for slower chaffing.
+   * Fix embedded copy of Argon2 to not use Word64, fixing build on 32 bit
+     systems.
+   * Randomize the server list.
+   * Don't upload more than neededshares-1 shares to Alternate servers
+     without asking the user if they want to do this potentially dangerous
+     action.
+   * Added a second keysafe server to the server list. It's provided
+     by Marek Isalski at Faelix. Currently located in UK, but planned move
+     to CH. Currently at Alternate level until verification is complete.
+   * Server: --motd can be used to provide a Message Of The Day.
+   * Added --check-servers mode, which is useful both at the command line
+     to see what servers keysafe knows about, and as a cron job.
+   * Server: Round number of objects down to the nearest thousand, to avoid
+     leaking too much data about when objects are uploaded to servers.
+   * Filter out escape sequences and any other unusual characters when
+     writing all messages to the console."""]]
\ No newline at end of file

fix url
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 72d7e61..334df3b 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -143,7 +143,7 @@ source of disk IO.
 
 It's early days still, but keysafe's server code works well enough.
 
-* `git clone git://git.joeyh.name/code/keysafe`
+* `git clone git://git.joeyh.name/keysafe`
 * Be sure to verify the gpg signature of the git repository!
 * You will need to install keysafe from source; see its INSTALL file.
   Use `make install` to install it, including a systemd service file.

blog update
diff --git a/blog/entry/keysafe_beta_release.mdwn b/blog/entry/keysafe_beta_release.mdwn
new file mode 100644
index 0000000..b09deb2
--- /dev/null
+++ b/blog/entry/keysafe_beta_release.mdwn
@@ -0,0 +1,25 @@
+After a month of development, [[code/keysafe]] 0.20160922 is released, 
+and ready for beta testing. And it needs servers.
+
+With this release, the whole process of backing up and restoring a gpg
+secret key to keysafe servers is implemented. Keysafe is started at desktop
+login, and will notice when a gpg secret key has been created, and prompt
+to see if it should back it up.
+
+At this point, I recommend only using keysafe for lower-value secret keys,
+for several reasons:
+
+* There could be some bug that prevents keysafe from restoring a backup.
+* Keysafe's design has not been completely reviewed for security.
+* None of the keysafe servers available so far or planned to be deployed
+  soon meet all of the security requirements for a recommended keysafe server.
+  While server security is only the initial line of defense, it's still
+  important.
+
+Currently the only keysafe server is one that I'm running myself.
+Two more keysafe servers are needed for keysafe to really be usable,
+and I can't run those.
+
+If you're interested in running a keysafe server, read
+[[the_keysafe_server_requirements|code/keysafe/servers]]
+and get in touch.

update
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 579a55d..72d7e61 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -130,7 +130,9 @@ Each key takes a minimum of 64 KiB to store, perhaps more for gpg keys
 with lots of signatures. So 10 GiB of disk is sufficient for 160 thousand
 users, which is enough for a small keysafe server.
 
-The keysafe server uses very little memory and CPU.
+The keysafe server uses very little memory and CPU. It does rate limiting
+with client-side proof-of-work to prevent it being abused for
+general-purpose data storage.
 
 There is some disk IO overhead, because keysafe updates the mtime and ctime
 of all shards stored on the server, as frequently as every 30 minutes.
@@ -141,7 +143,7 @@ source of disk IO.
 
 It's early days still, but keysafe's server code works well enough.
 
-* git clone keysafe
+* `git clone git://git.joeyh.name/code/keysafe`
 * Be sure to verify the gpg signature of the git repository!
 * You will need to install keysafe from source; see its INSTALL file.
   Use `make install` to install it, including a systemd service file.
@@ -153,5 +155,5 @@ It's early days still, but keysafe's server code works well enough.
 * Once ready, email id@joeyh.name to get added to keysafe's server list.
 
 Here's a the [[code/propellor]] config for my own keysafe server:
-<http://source.propellor.branchable.com/?p=source.git;a=blob;f=joeyconfig.hs;h=fa37e97ba94eecf8f4cbe47d41fbc7c1cd89723b;hb=HEAD#l461>
+<http://source.propellor.branchable.com/?p=source.git;a=blob;f=joeyconfig.hs;h=15a00f7c2dffa15ed275fdd44e84e2edcc226559;hb=b9f87f0c08d94c5d43224a2c6bbacb332ebfc1b6#l460>
 --[[Joey]]

add news item for keysafe 0.20160922
diff --git a/code/keysafe/news/version_0.20160922.mdwn b/code/keysafe/news/version_0.20160922.mdwn
new file mode 100644
index 0000000..0cf5ac8
--- /dev/null
+++ b/code/keysafe/news/version_0.20160922.mdwn
@@ -0,0 +1,17 @@
+keysafe 0.20160922 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Keysafe now knows about 3 servers, although only 1 is currently in
+     operation. It will queue uploads to the other 2 servers until
+     they are added in a later keysafe release.
+   * Added --autostart mode, and make both keysafe --backup and
+     the Makefile install a FDO desktop autostart file to use it.
+   * In --autostart mode, retry any queued uploads.
+   * In --autostart mode, check for gpg keys that have not been
+     backed up, and offer to back them up. Only ask once per key.
+   * Changed format of ~/.keysafe/backup.log
+   * Server: Reduce number of buckets in rate limiter, avoiding ones with very low
+     proof of work.
+   * Server: Make rate limiter adapt to ongoing load more quickly -- every 15
+     minutes instead of every 60.
+   * Server: Added --backup-server and --restore-server to aid in backing
+     up keysafe servers with minimal information leakage."""]]
\ No newline at end of file

let's not mix
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 7c5c755..579a55d 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -80,10 +80,8 @@ lhmhvShr0WRqB8fWYPkc
 ### Alternate
 
 * Keysafe port only exposed via tor hidden service.
-* Dedicated to only running keysafe, no other services. (Other than ssh for
-  admin) (Since it's running tor, it's also ok to be a tor bridge, or
-  relay; this way unused bandwidth benefits the tor network. However, see
-  [here](https://trac.torproject.org/projects/tor/ticket/8742).)
+* Dedicated to only running keysafe, no other services. (Other than tor and 
+  ssh for admin)
 * The set of people who administer the server, and procedures for giving
   others access is well-defined.
 * Noone who has access to the server also has access to any Recommended

note
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index cff7c90..7c5c755 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -82,7 +82,8 @@ lhmhvShr0WRqB8fWYPkc
 * Keysafe port only exposed via tor hidden service.
 * Dedicated to only running keysafe, no other services. (Other than ssh for
   admin) (Since it's running tor, it's also ok to be a tor bridge, or
-  relay; this way unused bandwidth benefits the tor network.)
+  relay; this way unused bandwidth benefits the tor network. However, see
+  [here](https://trac.torproject.org/projects/tor/ticket/8742).)
 * The set of people who administer the server, and procedures for giving
   others access is well-defined.
 * Noone who has access to the server also has access to any Recommended

update
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index af743f2..cff7c90 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -100,17 +100,14 @@ lhmhvShr0WRqB8fWYPkc
   It may be better to run some servers without backups and adjust the
   number of shards needed to recover keys; a server losing its data
   need not be catastrophic.)
-* Any backup does not record the whole history of the /var/lib/keysafe
-  directory. Doing so interferes with keysafe's obscuring of when shards
-  were stored on the server.
-
-  It may be useful to keep some old versions of /var/lib/keysafe so that
-  if files get accidentially deleted, they can be recovered. For example,
-  one version for each of the past 7 days, and past 4 weeks.
-  But bear in mind that this lets anyone who can access those backups
-  make guesses about what shares belong with other shares stored on other
-  servers in the same time period. See [[details]] for how that makes it 
-  somewhat easier for an attacker.
+* Any backup should take care to not leak information about what objects
+  were present on the server at multiple times in the past. That would 
+  let an attacker who can access the backups make guesses about shares
+  belong with other shares stored on other servers in the same time period.
+  See [[details]] for how that makes it somewhat easier for an attacker.
+
+  keysafe --backup-server can be used to generate encrypted files to back up,
+  in a way that is designed to avoid these problems.
 
 * Similarly, the filesystem and storage system should not allow rolling back
   to old snapshots.

more on incremental backups
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 6fdf95c..af743f2 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -100,9 +100,18 @@ lhmhvShr0WRqB8fWYPkc
   It may be better to run some servers without backups and adjust the
   number of shards needed to recover keys; a server losing its data
   need not be catastrophic.)
-* Any backup is *not* incremental. Incremental backups interfere with
-  keysafe's obscuring of when shards were stored on the server, and can
-  be used in correlation attacks.
+* Any backup does not record the whole history of the /var/lib/keysafe
+  directory. Doing so interferes with keysafe's obscuring of when shards
+  were stored on the server.
+
+  It may be useful to keep some old versions of /var/lib/keysafe so that
+  if files get accidentially deleted, they can be recovered. For example,
+  one version for each of the past 7 days, and past 4 weeks.
+  But bear in mind that this lets anyone who can access those backups
+  make guesses about what shares belong with other shares stored on other
+  servers in the same time period. See [[details]] for how that makes it 
+  somewhat easier for an attacker.
+
 * Similarly, the filesystem and storage system should not allow rolling back
   to old snapshots.
 

allow servers to also run as tor bridges etc
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 554d893..6fdf95c 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -80,8 +80,9 @@ lhmhvShr0WRqB8fWYPkc
 ### Alternate
 
 * Keysafe port only exposed via tor hidden service.
-* Dedicated to only running keysafe, no other services (other than ssh for
-  admin)
+* Dedicated to only running keysafe, no other services. (Other than ssh for
+  admin) (Since it's running tor, it's also ok to be a tor bridge, or
+  relay; this way unused bandwidth benefits the tor network.)
 * The set of people who administer the server, and procedures for giving
   others access is well-defined.
 * Noone who has access to the server also has access to any Recommended

add news item for keysafe 0.20160914
diff --git a/code/keysafe/news/version_0.20160914.mdwn b/code/keysafe/news/version_0.20160914.mdwn
new file mode 100644
index 0000000..9b0dcd1
--- /dev/null
+++ b/code/keysafe/news/version_0.20160914.mdwn
@@ -0,0 +1,21 @@
+keysafe 0.20160914 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix bug that prevented keysafe --server from running when there was no
+     controlling terminal and zenity was not installed.
+   * Added --name and --othername options.
+   * Added proof of work to client/server protocol.
+   * Server-side rate limiting and DOS protection.
+   * server: Added --months-to-fill-half-disk option, defaulting to 12.
+   * Several new dependencies.
+   * Another fix to gpg secret key list parser.
+   * Warn when uploads fail and are put in the upload queue.
+   * Warn when --uploadqueued fails to upload to servers.
+   * Fix --uploadqueued bug that prevented deletion of local queued file.
+   * Added --chaff mode which uploads random junk to servers.
+     This is useful both to test the server throttling of uploads,
+     and to make it harder for servers to know if an object actually
+     contains secret key information.
+   * Store information about backed up keys in ~/.keysafe/backup.log
+     This can be deleted by the user at any time, but it's useful
+     in case a server is known to be compromised, or a problem is found
+     with keysafe's implementation that makes a backup insecure."""]]
\ No newline at end of file

comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_7_266728691c8dc55601cdcf589a4afbd6._comment b/blog/entry/PoW_bucket_bloom/comment_7_266728691c8dc55601cdcf589a4afbd6._comment
new file mode 100644
index 0000000..13ffc9e
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_7_266728691c8dc55601cdcf589a4afbd6._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 7"""
+ date="2016-09-14T01:14:15Z"
+ content="""
+Another bonus to using HMAC is that a large/distributed keysafe server cluster's
+nodes can all share the secret used to generate a request id, and then any
+node will accept a request id that was produced by any node. So that might
+be very useful in future scaling. Thanks for the help improving that part
+of this!
+"""]]

update
diff --git a/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment b/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment
index f3cbced..e25b393 100644
--- a/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment
+++ b/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment
@@ -5,4 +5,13 @@
  content="""
 SYN cookies rely on knowing the client's IP address. Keysafe, as a TOR hidden
 service, does not have such a means to distinguish clients.
+
+But, SYN cookie's use of a cryptographic hash makes me think of an HMAC.
+Could generate a request ID by `(hmac secret random, random)`. Then the
+server can verify incoming request IDs using the secret.
+
+That does seem to be simple enough to be worth implementing, to get rid of
+that first bloom filter. Thanks guys!
+
+"mac PoW bucket bloom"? :)
 """]]

comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment b/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment
new file mode 100644
index 0000000..f3cbced
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 6"""
+ date="2016-09-13T23:57:12Z"
+ content="""
+SYN cookies rely on knowing the client's IP address. Keysafe, as a TOR hidden
+service, does not have such a means to distinguish clients.
+"""]]

Added a comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_5_2d23a1fba91fedac5761196d26d7b211._comment b/blog/entry/PoW_bucket_bloom/comment_5_2d23a1fba91fedac5761196d26d7b211._comment
new file mode 100644
index 0000000..8164abb
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_5_2d23a1fba91fedac5761196d26d7b211._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="mju"
+ subject="comment 5"
+ date="2016-09-13T23:23:48Z"
+ content="""
+Just a suggestion: Maybe something like the technique for syn cookies works better and faster than asymmetric cryptography.
+"""]]

update
diff --git a/blog/entry/PoW_bucket_bloom.mdwn b/blog/entry/PoW_bucket_bloom.mdwn
index 585dcb2..91b91fe 100644
--- a/blog/entry/PoW_bucket_bloom.mdwn
+++ b/blog/entry/PoW_bucket_bloom.mdwn
@@ -30,10 +30,12 @@ necessary. At the worst, a client may have to do 8-16 minutes of work to
 access a keysafe server that is under heavy load, which would not be ideal,
 but is acceptible for keysafe since it's not run very often.
 
-(If the client provides a PoW good enough to allow accessing the last token
+If the client provides a PoW good enough to allow accessing the last token
 bucket, the request will be accepted even when that bucket is drained. The
 client has done plenty of work at this point, so it would be annoying to
-reject it.)
+reject it. To prevent an attacker that is willing to burn CPU from abusing
+this loophole to flood the server with object stores, the server delays
+until the last token bucket fills back up.
 
 ----
 
@@ -81,7 +83,7 @@ will have plenty of time to complete its proof of work.
 This sounds complicated, and probably it is, but the implementation only
 took 333 lines of code. About the same number of lines that it took to
 implement the entire keysafe HTTP client and server using the amazing
-[servant](http://hackage.haskell.org/package/servant) library. 
+[servant](http://hackage.haskell.org/package/servant) library.
 
 There are a number of knobs that may need to be tuned to dial it in,
 including the size of the token buckets, their refill rate, the size of the
@@ -90,3 +92,10 @@ Servers may eventually need to adjust those on the fly, so that if someone
 decides it's worth burning large quantities of CPU to abuse keysafe for
 general data storage, the server throttles down to a rate that will take
 a very long time to fill up its disk.
+
+This protects against DOS attacks that fill up the keysafe server storage.
+It does not prevent a determined attacker, who has lots of CPU to burn,
+from flooding so many requests that legitimate clients are forced to do
+an expensive proof of work and then time out waiting for the server. But
+that's an expensive attack to keep running, and the proof of work can 
+be adjusted to make it increasingly expensive.

simplify
diff --git a/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment b/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment
index fc3ca90..b110b70 100644
--- a/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment
+++ b/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment
@@ -3,29 +3,5 @@
  subject="""comment 3"""
  date="2016-09-13T16:48:56Z"
  content="""
-Also, I found another use for the meta-token-bucket, as Josh calls it.
-
-Recall that, if a client provides a maximum size proof of work, it's always
-allowed to store data. This forgiveness of the last token bucket being
-drained is nice, but also problimatic.
-
-A determined attacker, who is willing to burn enough CPU (probably hundreds
-or thousands of CPUS) can flood in requests that all have maximum PoW. Such
-an attacker could pretty quickly fill up the keysafe server storage.
-That wouldn't be economical for data storage, but it would be economical to
-DOS keysafe.
-
-The meta-token-bucket though, can be tuned to guard against that.
-The keysafe server can delay generating request IDs when it's empty,
-and so throttle back such an attacker. The refill rate can be tuned
-to be such that such an attack can't store any more data than would be
-stored if keysafe didn't always accept maximum sized PoW.
-
-The meta-token-bucket can have a high burst size (tends to hundreds
-of thousands of tokens), and refill somewhat slowly (eg one token per
-minute) and so not cause any delays except for in such a DOS scenario.
-
-----
-
-(Oh yeah, asymetric crypto would be the way to go.)
+Oh yeah, asymetric crypto would be the way to go.
 """]]

comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_3_c05ea3d9d10d17337c54227432377203._comment b/blog/entry/PoW_bucket_bloom/comment_3_c05ea3d9d10d17337c54227432377203._comment
deleted file mode 100644
index 9ff8c1e..0000000
--- a/blog/entry/PoW_bucket_bloom/comment_3_c05ea3d9d10d17337c54227432377203._comment
+++ /dev/null
@@ -1,25 +0,0 @@
-[[!comment format=mdwn
- username="joey"
- subject="""comment 3"""
- date="2016-09-13T16:48:56Z"
- content="""
-Also, I found another use for the meta-token-bucket, as Josh calls it.
-
-Recall that, if a client provides a maximum size proof of work, it's always
-allowed to store data. This forgiveness of the last token bucket being
-drained is "nice", but also problimatic.
-
-A determined attacker, who is willing to burn enough CPU (probably hundreds
-or thousands of CPUS) can flood in requests that all have maximum PoW. Such
-an attacker could pretty quickly fill up the keysafe server storage.
-
-The meta-token-bucket though, can be tuned to guard against that.
-The keysafe server can delay generating request IDs when it's empty,
-and so throttle back such an attacker. The refill rate can be tuned
-to be such that such an attack doesn't store any more data than would be
-stored if keysafe didn't always accept maximum sized PoW.
-
-The meta-token-bucket can have a high burst size (tends to hundreds
-of thousands of tokens), and refill somewhat slowly (eg one token per
-minute) and so not cause any delays except for in such a DOS scenario.
-"""]]
diff --git a/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment b/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment
new file mode 100644
index 0000000..fc3ca90
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment
@@ -0,0 +1,31 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2016-09-13T16:48:56Z"
+ content="""
+Also, I found another use for the meta-token-bucket, as Josh calls it.
+
+Recall that, if a client provides a maximum size proof of work, it's always
+allowed to store data. This forgiveness of the last token bucket being
+drained is nice, but also problimatic.
+
+A determined attacker, who is willing to burn enough CPU (probably hundreds
+or thousands of CPUS) can flood in requests that all have maximum PoW. Such
+an attacker could pretty quickly fill up the keysafe server storage.
+That wouldn't be economical for data storage, but it would be economical to
+DOS keysafe.
+
+The meta-token-bucket though, can be tuned to guard against that.
+The keysafe server can delay generating request IDs when it's empty,
+and so throttle back such an attacker. The refill rate can be tuned
+to be such that such an attack can't store any more data than would be
+stored if keysafe didn't always accept maximum sized PoW.
+
+The meta-token-bucket can have a high burst size (tends to hundreds
+of thousands of tokens), and refill somewhat slowly (eg one token per
+minute) and so not cause any delays except for in such a DOS scenario.
+
+----
+
+(Oh yeah, asymetric crypto would be the way to go.)
+"""]]

comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_3_c05ea3d9d10d17337c54227432377203._comment b/blog/entry/PoW_bucket_bloom/comment_3_c05ea3d9d10d17337c54227432377203._comment
new file mode 100644
index 0000000..9ff8c1e
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_3_c05ea3d9d10d17337c54227432377203._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2016-09-13T16:48:56Z"
+ content="""
+Also, I found another use for the meta-token-bucket, as Josh calls it.
+
+Recall that, if a client provides a maximum size proof of work, it's always
+allowed to store data. This forgiveness of the last token bucket being
+drained is "nice", but also problimatic.
+
+A determined attacker, who is willing to burn enough CPU (probably hundreds
+or thousands of CPUS) can flood in requests that all have maximum PoW. Such
+an attacker could pretty quickly fill up the keysafe server storage.
+
+The meta-token-bucket though, can be tuned to guard against that.
+The keysafe server can delay generating request IDs when it's empty,
+and so throttle back such an attacker. The refill rate can be tuned
+to be such that such an attack doesn't store any more data than would be
+stored if keysafe didn't always accept maximum sized PoW.
+
+The meta-token-bucket can have a high burst size (tends to hundreds
+of thousands of tokens), and refill somewhat slowly (eg one token per
+minute) and so not cause any delays except for in such a DOS scenario.
+"""]]

Added a comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_3_610123f7b53662d2d9be2d24cf597477._comment b/blog/entry/PoW_bucket_bloom/comment_3_610123f7b53662d2d9be2d24cf597477._comment
new file mode 100644
index 0000000..c2370bb
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_3_610123f7b53662d2d9be2d24cf597477._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="josh@ccccabe84317e1b7429fd465de0b38fd54925dea"
+ nickname="josh"
+ subject="comment 3"
+ date="2016-09-13T16:51:45Z"
+ content="""
+I was thinking of asymmetric crypto, but yeah, using additional crypto does mean much more careful analysis.
+"""]]

comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_2_b8c8bfe5e23ef4ea28460f7872ab1d4f._comment b/blog/entry/PoW_bucket_bloom/comment_2_b8c8bfe5e23ef4ea28460f7872ab1d4f._comment
new file mode 100644
index 0000000..5220de0
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_2_b8c8bfe5e23ef4ea28460f7872ab1d4f._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2016-09-13T16:10:27Z"
+ content="""
+That is indeed a good idea Josh. If the bloom filter memory
+use ever comes to be a problem that would be a good way to at half it.
+
+It does add a fair bit of complexit. So many gotchas involved in
+using AES. Reusing an IV might allow key recovery attacks..
+
+The 64 mb or so that would be freed is probably going to be peanuts on the
+average keysafe server (even if it's a fairly low-spec arm box), since
+they're supposed to be bare-metal servers only running keysafe.
+"""]]

Added a comment: Signed tokens?
diff --git a/blog/entry/PoW_bucket_bloom/comment_1_5b3479923bddc661d27a7c2482df9316._comment b/blog/entry/PoW_bucket_bloom/comment_1_5b3479923bddc661d27a7c2482df9316._comment
new file mode 100644
index 0000000..000ee94
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_1_5b3479923bddc661d27a7c2482df9316._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="josh@ccccabe84317e1b7429fd465de0b38fd54925dea"
+ nickname="josh"
+ subject="Signed tokens?"
+ date="2016-09-13T07:39:44Z"
+ content="""
+To avoid having to store not-yet-used request IDs even in a bloom filter, what about signing them using a server key, handing them to the client, and then throwing them away?  You can verify when you get the request ID back that it has a valid signature, so you've effectively let the client store it for you, indefinitely.
+
+You'd still need the mechanism to remember *used* request IDs to avoid reuse, but you wouldn't have to store unused request IDs, which reduces memory usage and potentially avoids the need for the meta-token-bucket for request IDs.
+"""]]

blog
diff --git a/blog/entry/PoW_bucket_bloom.mdwn b/blog/entry/PoW_bucket_bloom.mdwn
new file mode 100644
index 0000000..585dcb2
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom.mdwn
@@ -0,0 +1,92 @@
+[[!meta title="PoW bucket bloom: throttling anonymous clients with proof of work, token buckets, and bloom filters"]]
+
+An interesting side problem in [[code/keysafe]]'s design is that keysafe
+servers, which run as tor hidden services, allow anonymous data storage and
+retrieval. While each object is limited to 64 kb, what's to stop someone
+from making many requests and using it to store some big files?
+
+The last thing I want is a [[code/git-annex]] keysafe special remote. ;-)
+
+I've done a mash-up of three technologies to solve this,
+that I think is perhaps somewhat novel. Although it could be entirely old
+hat, or even entirely broken. (All I know so far is that the code
+compiles.) It uses proof of work, token buckets, and bloom filters.
+
+----
+
+Each request can have a proof of work attached to it, which is just a value
+that, when hashed with a salt, starts with a certain number of 0's.
+The salt includes the ID of the object being stored or retrieved.
+
+The server maintains a list of token buckets. The first can be accessed
+without any proof of work, and subsequent ones need progressively more
+proof of work to be accessed.
+
+Clients will start by making a request without a PoW, and that will often
+succeed, but when the first token bucket is being drained too fast by other
+load, the server will reject the request and demand enough proof of work
+to allow access to the second token bucket. And so on down the line if
+necessary. At the worst, a client may have to do 8-16 minutes of work to
+access a keysafe server that is under heavy load, which would not be ideal,
+but is acceptible for keysafe since it's not run very often.
+
+(If the client provides a PoW good enough to allow accessing the last token
+bucket, the request will be accepted even when that bucket is drained. The
+client has done plenty of work at this point, so it would be annoying to
+reject it.)
+
+----
+
+So far so simple really, but this has a big problem: What prevents a proof
+of work from being reused? An attacker could generate a single PoW good
+enough to access all the token buckets, and flood the server with requests
+using it, and so force everyone else to do excessive amounts of work to use
+the server.
+
+Guarding against that DOS is where the bloom filters come in. The server
+generates a random request ID, which has to be included in the PoW salt and
+sent back by the client along with the PoW. The request ID is added to a
+bloom filter, which the server can use to check if the client is providing
+a request ID that it knows about. And a second bloom filter is used to
+check if a request ID has been used by a client before, which prevents the
+DOS.
+
+Of course, when dealing with bloom filters, it's important to consider what
+happens when there's a rare false positive match. This is not a problem with
+the first bloom filter, because a false positive only lets some made-up
+request ID be used. A false positive in the second bloom filter will cause
+the server to reject the client's proof of work. But the server can just
+request more work, or send a new request ID, and the client will follow
+along.
+
+The other gotcha with bloom filters is that filling them up too far
+sets too many bits, and so false positive rates go up. To deal with this,
+keysafe just keeps count of how many request IDs it has generated, and once
+it gets to be too many to fit in a bloom filter, it makes a new, empty
+bloom filter and starts storing request IDs in it. The old bloom filter is
+still checked too, providing a grace period for old request IDs to be used.
+Using bloom filters that occupy around 32 mb of RAM, this rotation
+only has to be done every million requests of so.
+
+But, that rotation opens up another DOS! An attacker could cause lots of
+request IDs to be generated, and so force the server to rotate its bloom
+filters too quickly, which would prevent any requests from being accepted.
+To solve this DOS, just use one more token bucket, to limit the rate
+that request IDs can be generated, so that the time it would take an
+attacker to force a bloom filter rotation is long enough that any client
+will have plenty of time to complete its proof of work.
+
+----
+
+This sounds complicated, and probably it is, but the implementation only
+took 333 lines of code. About the same number of lines that it took to
+implement the entire keysafe HTTP client and server using the amazing
+[servant](http://hackage.haskell.org/package/servant) library. 
+
+There are a number of knobs that may need to be tuned to dial it in,
+including the size of the token buckets, their refill rate, the size of the
+bloom filters, and the number of argon2 iterations in the proof of work.
+Servers may eventually need to adjust those on the fly, so that if someone
+decides it's worth burning large quantities of CPU to abuse keysafe for
+general data storage, the server throttles down to a rate that will take
+a very long time to fill up its disk.

better DOS protection with bloom filters
diff --git a/code/keysafe/details.mdwn b/code/keysafe/details.mdwn
index aafc9b2..4b18e32 100644
--- a/code/keysafe/details.mdwn
+++ b/code/keysafe/details.mdwn
@@ -197,18 +197,15 @@ DOS attacks.
 
 Assuming that the client communicates with the server over http:
 
-	PUT /keysafe/objects/N?S
-	GET /keysafe/objects/N?S
+	PUT /keysafe/objects/N
+	GET /keysafe/objects/N
 
 The server's response can be either the result of the request,
 or a proof of work requirement, which specifies the difficulty D 
-(number of 0's needed), random value R, and the number of argon2
-iterations. The client provides the proof of work in S, which is a 
-string such that argon2(N,S+R) starts with a given number of 0's.
-
-The random value R is picked when the server starts up, and may be changed
-from time to time. It prevents a client from reusing proofs of work 
-between servers, and is also useful to mitigate DOS attacks.
+(number of 0's needed), random salt RS, and the number of argon2
+iterations. The client provides the proof of work in a query parameter,
+which is a string S such that argon2(N,S+RS) starts with a given number
+of 0's.
 
 (The server should only be able to control the number of iterations,
 not other argon2 parameters, to avoid forcing the client to use too much
@@ -230,18 +227,18 @@ token every minute, then the maximum allowed throughput is 4 requests
 per minute. If calculating the proof of work takes 2^D seconds on average, 
 then it will take on average 16 minutes work to access B4.
 
-Since this scheme is stateless, it lets an attacker do work once for a
-given N and then flood the server with repeated requests for N?S, reusing the
-proof of work. This is a DOS because the attacker can keep all the token
-buckets drained and so not let legitimate requests through. But, the server
-can detect when this DOS is occurring (when a proof of work allows
-accessing the last token bucket, and the bucket is empty), and pick a new R
-(and also perhaps increase the number of argon2 iterations to make the PoW
-a little bit harder). This invalidates the attacker's cached proof of work,
-and gives other clients a chance to get some requests through while the
-attacker is generating new proofs of work for the new R. Another defense
-against this attack is for the server to keep a small cache of recent N's
-(expiring after an hour) and reject repeated requests for them.
+The server can generate a different RS for each request, and can
+insert them into a bloom filter to keep track of ones it has given out.
+Bloom filter false positives are not a problem because they are quite
+rare and so it is not efficient for a client to make up RS in hope that
+there will be a false positive.
+
+To guard against DOS attacks that reuse proofs of work, the server can
+maintain a second bloom filter, putting RS into it once it's used, and
+rejecting attempts that reuse a RS. Since the bloom filter will
+(with a low probability) yield a false positive, the server should reject
+an attempt by generating a new RS' and requesting a new proof of work from
+the client.
 
 ## Avoiding correlations
 

better PoW design
diff --git a/code/keysafe/details.mdwn b/code/keysafe/details.mdwn
index 925c16d..aafc9b2 100644
--- a/code/keysafe/details.mdwn
+++ b/code/keysafe/details.mdwn
@@ -18,7 +18,7 @@
 * Servers reject attempts to store an object under a name that is
   already in use.
 * Servers do not allow enumerating all objects stored,
-  and require a proof of work client puzzle to handle any request.
+  and require a proof of work to handle any request.
 * Upload S1-S3 to separate servers under the names N1-N3.
   If any of the uploads is rejected as name already in use, 
   ask user to enter a different name or password.
@@ -72,7 +72,7 @@ choose a strong password. A name that attackers are unlikely to guess
 prevents this attack, which is why keysafe prompts for not only the
 user's name, but also a more obscure name. Each name guess that the
 attacker makes takes 10 minutes of CPU time to generate N, as well
-as whatever work the servers impose to solve their client puzzle.
+as whatever proof of work the servers require.
 
 The sharding prevents a single malicious server from blindly 
 guessing weak passwords across its entire collection of objects.
@@ -147,13 +147,15 @@ in gpg to compromise the user's system.
 There's a server list shipped with the client, giving their tor onion address
 and the organization providing the server. 
 
-Three of the servers in the list are designated default servers.
+Three of the servers in the list are recommended servers.
 Shards are stored on these unless overridden by other configuration.
 
-When recovering a key, the client tries the default servers first. But, if
-it fails to recover the key using those, it goes on to try other servers on
-the list. This way we don't need to remember which servers the shards were
-stored on, and can change the default servers when necessary.
+When recovering a key, the client tries the recommended servers first. But,
+if it fails to recover the key using those, it goes on to try other servers
+on the list. This way we don't need to remember which servers the shards
+were stored on, and can change the recommended servers when necessary.
+
+See [[servers]] for more on the server list.
 
 ## Servers
 
@@ -183,38 +185,63 @@ Objects shoud be padded to a fixed size before they are encrypted, to
 prevent attackers from correlating and targeting particular objects based
 on size.
 
-## Client puzzles
+## client-server Proof of Work
+
+The Proof of Work prevents servers being flooded with requests.
+This is particularly important to prevent misuse of keysafe servers
+to store large data on them. It's also somewhat useful to prevent attackers
+guessing the name someone used to store a key; but the cost of generating
+N from a name makes the server's proof of work only a secondary line of
+defense against such an attack. Finally, PoW is useful to protect against
+DOS attacks.
 
 Assuming that the client communicates with the server over http:
 
 	PUT /keysafe/objects/N?S
 	GET /keysafe/objects/N?S
 
-Then, the S can be required to be a string such that argon2(N,S)
-starts with a given number of 0's. This allows the server to verify the
-client's proof of work without maintaining any state.
-
-The required number of 0's can be queried:
-
-	GET /keysafe/proofofwork/
+The server's response can be either the result of the request,
+or a proof of work requirement, which specifies the difficulty D 
+(number of 0's needed), random value R, and the number of argon2
+iterations. The client provides the proof of work in S, which is a 
+string such that argon2(N,S+R) starts with a given number of 0's.
 
-With a response like "zeros=4 iterations=1".
+The random value R is picked when the server starts up, and may be changed
+from time to time. It prevents a client from reusing proofs of work 
+between servers, and is also useful to mitigate DOS attacks.
 
 (The server should only be able to control the number of iterations,
 not other argon2 parameters, to avoid forcing the client to use too much
 memory. Normally, the server will keep iterations small, probably 1,
-since it does need to calculate the argon2 hash itself.)
-
-Note that this scheme lets a client do work once for a given N and then
-request that N from multiple servers, as long as they have similar zeros=
-parameters (and the same iterations= parameters). This is probably a good
-thing; it means that keysafe doesn't need to do extra work when checking
-servers to get a shard.
-
-Servers can change their proof of work parameters as needed, but that can
-cause a client that was connected to the server to generate a bad POW.
-The server can respond with 402 Payment Required in that case, so the
-client knows to retry.
+since it does need to calculate the argon2 hash once itself.)
+
+The server can use a [token bucket](https://en.wikipedia.org/wiki/Token_bucket)
+to throttle requests to a given rate. In fact, there can be a whole
+series of token buckets B0,B1.., for increasing difficulty proofs of work.
+
+A request without a proof of work is checked in B0. If that bucket is empty,
+the server responds with a proof of work requirement D=1, and
+the client makes a new request whose proof of work allows access to B1.
+If the server is under load, B1 might also be empty, and so the client 
+will have to try again with D=2 to access B2, and so on.
+
+If there are 4 buckets, and each bucket refills at the rate of a
+token every minute, then the maximum allowed throughput is 4 requests
+per minute. If calculating the proof of work takes 2^D seconds on average, 
+then it will take on average 16 minutes work to access B4.
+
+Since this scheme is stateless, it lets an attacker do work once for a
+given N and then flood the server with repeated requests for N?S, reusing the
+proof of work. This is a DOS because the attacker can keep all the token
+buckets drained and so not let legitimate requests through. But, the server
+can detect when this DOS is occurring (when a proof of work allows
+accessing the last token bucket, and the bucket is empty), and pick a new R
+(and also perhaps increase the number of argon2 iterations to make the PoW
+a little bit harder). This invalidates the attacker's cached proof of work,
+and gives other clients a chance to get some requests through while the
+attacker is generating new proofs of work for the new R. Another defense
+against this attack is for the server to keep a small cache of recent N's
+(expiring after an hour) and reject repeated requests for them.
 
 ## Avoiding correlations
 

teleconsole is yet another option
diff --git a/code/debug-me/discussion.mdwn b/code/debug-me/discussion.mdwn
index 8027f1a..ab5c469 100644
--- a/code/debug-me/discussion.mdwn
+++ b/code/debug-me/discussion.mdwn
@@ -10,6 +10,7 @@ Some similar projects you may be interested in looking at, if only for "how not
 * [Mosh][] - the mobile shell, interesting concepts of local terminal emulation and predictive capabilities
 * [Monkeysphere][] - OpenPGP web of trust applied to SSH and HTTP servers and clients
 * [watch-my-terminal][] - Allows a remote users to watch your terminal session via any modern browser (script+node on the broadcaster side, javascript on the watchers' side). Terminal emulation is quite good; it correctly renders vim, less and aptitude.
+* [teleconsole][] - can share terminal sessions through SSH or the browser through a SSH proxy
 
 [Gitso]: https://code.google.com/archive/p/gitso/
 [more recent fork]: https://github.com/AustP/Gitso
@@ -19,5 +20,6 @@ Some similar projects you may be interested in looking at, if only for "how not
 [Mosh]: https://mosh.mit.edu/
 [Monkeysphere]: http://web.monkeysphere.info
 [watch-my-terminal]: https://jasonwoof.com/gitweb/?p=watch-my-terminal.git;a=tree
+[teleconsole]: https://github.com/gravitational/teleconsole
 
 It would seem to me preferable to reuse existing components (SSH, especially) instead of reinventing the wheel too much here. So much trouble with terminal emulation and so on, as I am sure you know...

comment
diff --git a/blog/entry/hiking_the_Roan/comment_2_4e7a05cd8a2fb55ec0122da231908be1._comment b/blog/entry/hiking_the_Roan/comment_2_4e7a05cd8a2fb55ec0122da231908be1._comment
new file mode 100644
index 0000000..cbd66d5
--- /dev/null
+++ b/blog/entry/hiking_the_Roan/comment_2_4e7a05cd8a2fb55ec0122da231908be1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2016-09-08T15:17:54Z"
+ content="""
+I actually did that hike with my laptop in my pack because I
+needed it on the larger trip for other reasons and did not want to
+leave it unattended in my car overnight. Even with trash bags to protect
+from moisture, that was very suboptimal, do not recommend.
+"""]]

note GLU/CPU comparison
diff --git a/code/keysafe/faq.mdwn b/code/keysafe/faq.mdwn
index 578b5b6..4512be7 100644
--- a/code/keysafe/faq.mdwn
+++ b/code/keysafe/faq.mdwn
@@ -44,6 +44,10 @@ Compare these numbers with the cost to crack keysafe passwords
 * Weak password (30 entropy): 51072 CPU-years 
 * Super-weak password (19 entropy): 25 CPU-years 
 
+(Note that is a comparison between GPU years and CPU years; SHA-1 used by
+gpg can easily be run fast on GPUs, while keysafe uses argon2 which is
+designed to be GPU-resistent.)
+
 Big difference! Indeed, the design of gpg prevents a really expensive hash
 being used to protect against passphrase cracking, because it would slow down
 day-to-day use of gpg. Keysafe can make cracking the password much more

Added a comment: question
diff --git a/blog/entry/hiking_the_Roan/comment_1_db91f5e569a74a87cff0a42b7d656906._comment b/blog/entry/hiking_the_Roan/comment_1_db91f5e569a74a87cff0a42b7d656906._comment
new file mode 100644
index 0000000..461ef89
--- /dev/null
+++ b/blog/entry/hiking_the_Roan/comment_1_db91f5e569a74a87cff0a42b7d656906._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="jmz@2d336904dde22d29d81d9ae1644d7e9db6613317"
+ nickname="jmz"
+ subject="question"
+ date="2016-09-08T01:20:39Z"
+ content="""
+Do you take a laptop or anything while you camp? PocketChip? Or just a digital camera? Just curious, I've taken a cheap laptop once.
+"""]]

corrections
thanks, kwadronaut
diff --git a/code/keysafe/faq.mdwn b/code/keysafe/faq.mdwn
index 098a017..578b5b6 100644
--- a/code/keysafe/faq.mdwn
+++ b/code/keysafe/faq.mdwn
@@ -10,7 +10,7 @@ theft, raids, and compromised printers. Gold standard.
 Using keysafe is analagous to storing the paperkey printout in a safety
 deposit box at a bank, and using a really really strong gpg passphrase.
 Since we don't trust a single bank (server), we shred the printout and
-evenly distribute the shreds amoung several banks. While the banks know the
+evenly distribute the shreds among several banks. While the banks know the
 safety deposit boxes belong to you and could put the shreds back together,
 a keysafe server has very little identifying information to go on (it only
 knows when you made the deposit).
@@ -19,10 +19,10 @@ knows when you made the deposit).
 
 So, you rely on your gpg passphrase for security.
 
-Gpg uses between 1024 (the default) and 65011712 rounds of SHA-1 hashing of
-the passphrase. In 2012, a GPU could calculate 2 billion SHA-1 hashes
-per second, so this is not much of an impediment to password cracking at
-all.
+Gpg uses between 1024 and 65011712 rounds of SHA-1 hashing of
+the passphrase, with the default probably being 65536. 
+In 2012, a GPU could calculate 2 billion SHA-1 hashes per second,
+so this is not much of an impediment to password cracking at all.
 
 Assuming 100 gpg passphrases can be tried per second, and gpg is
 configured to use the maximum rounds (which it normally is NOT):
@@ -55,7 +55,7 @@ Not recommended. Use a brain wallet.
 
 Keysafe might be more secure than a paper wallet in some situations.
 It's happened before that someone has stumbled over someone else's
-list of electrum words amoung their papers. Using keysafe avoids such
+list of electrum words among their papers. Using keysafe avoids such
 scenarios.
 
 #### How is keysafe different from other systems for private key backup/sync?

foo
diff --git a/code/keysafe/faq.mdwn b/code/keysafe/faq.mdwn
index 75f59de..098a017 100644
--- a/code/keysafe/faq.mdwn
+++ b/code/keysafe/faq.mdwn
@@ -60,7 +60,8 @@ scenarios.
 
 #### How is keysafe different from other systems for private key backup/sync?
 
-Here are some similar systems:
+Here are some similar systems, and intial impressions (which may be
+inaccurate; corrections welcomed):
 
 * [Whiteout](https://blog.whiteout.io/2014/07/07/secure-pgp-key-sync-a-proposal/)
   uses a 24 letter code to encrypt the secret key. This has to be written

improve
diff --git a/code/keysafe/faq.mdwn b/code/keysafe/faq.mdwn
index 1e33e4e..75f59de 100644
--- a/code/keysafe/faq.mdwn
+++ b/code/keysafe/faq.mdwn
@@ -58,7 +58,7 @@ It's happened before that someone has stumbled over someone else's
 list of electrum words amoung their papers. Using keysafe avoids such
 scenarios.
 
-#### Hw is keysafe different from other systems for private key backup/sync?
+#### How is keysafe different from other systems for private key backup/sync?
 
 Here are some similar systems:
 
@@ -75,7 +75,7 @@ Here are some similar systems:
   rate-limit logins and so avoid password cracking (except by the server).
   (This idea is worth keysafe stealing!)
 * [LEAP](https://leap.se/en/docs/tech/hard-problems#availability-problem)'s
-  [Soledad](https://leap.se/soledad) uses a large storage secret to encrypt
+  [Soledad](https://leap.se/soledad) uses a large secret to encrypt
   private keys. This can be stored in a recovery document in a recovery
   database, which anyone can make requests from. To prevent attacks,
   the recovery database delays responses, and a recovery code is needed

ideas
diff --git a/code/keysafe/details.mdwn b/code/keysafe/details.mdwn
index 4fd7fea..925c16d 100644
--- a/code/keysafe/details.mdwn
+++ b/code/keysafe/details.mdwn
@@ -296,3 +296,46 @@ Note that the argon2 hash parameters to vary between versions should not be
 merely the number of rounds, as that would allow an attacker to hash for
 each version's number of rounds in one pass. Instead, vary the hash
 memory parameter.
+
+## Ideas
+
+Some ideas for improvements to keysafe.
+
+### Assisted Password-based Key Derivation
+
+An idea from [Nigori](http://www.links.org/files/nigori/nigori-protocol-01.html#anchor15):
+
+If the user has an account at some server, the server can contribute part
+of the data used to generate the key encryption key K. So not only is the
+user's keysafe password needed for key recovery, but the user has to
+authenticate to the server. As well as adding entropy to K, the server 
+can do rate limiting to prevent password guessing.
+
+Risks include:
+
+* The server becomes a target to be compromised.
+* If the server goes down, the user loses the ability to recover their gpg
+  key from keysafe.
+
+### Entangled objects
+
+An idea from Anthony Towns:
+
+Two or more objects stored on a keysafe server can be entangled.
+When one of them is requested, the server should delete the others.
+
+This could be used in several ways:
+
+* Keysafe could upload random objects entangled with a key's object,
+  and keep local records of the names of the random objects. Then if the
+  user wants to stop storing a key on keysafe servers, keysafe can request
+  the entangled objects to (hopefully) delete the real objects from the
+  server.
+* Keysafe could pick or prompt for some tripwire names that an attacker
+  might try if they were looking for a user's data. Then an attacker
+  risks deleting the data stored on the server. Although this also has 
+  DOS potential.
+* The user could pick a real name and fake name and keysafe uploads
+  objects for both. If the user is being forced to give up their keysafe
+  name and password, they could provide the fake name, and if it were
+  used, their data would get deleted from the keysafe servers.