Recent changes to this wiki:

add news item for github-backup 1.20160207
diff --git a/code/github-backup/news/version_1.20141204.mdwn b/code/github-backup/news/version_1.20141204.mdwn
deleted file mode 100644
index 4d9fef2..0000000
--- a/code/github-backup/news/version_1.20141204.mdwn
+++ /dev/null
@@ -1,4 +0,0 @@
-github-backup 1.20141204 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Fix broken argument parser for the username|organization parameter.
-     Closes: #[772043](http://bugs.debian.org/772043)"""]]
\ No newline at end of file
diff --git a/code/github-backup/news/version_1.20160207.mdwn b/code/github-backup/news/version_1.20160207.mdwn
new file mode 100644
index 0000000..2d7fd4e
--- /dev/null
+++ b/code/github-backup/news/version_1.20160207.mdwn
@@ -0,0 +1,10 @@
+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

update
diff --git a/blog/entry/letsencrypt_support_in_propellor.mdwn b/blog/entry/letsencrypt_support_in_propellor.mdwn
index 2592c40..01c52b6 100644
--- a/blog/entry/letsencrypt_support_in_propellor.mdwn
+++ b/blog/entry/letsencrypt_support_in_propellor.mdwn
@@ -8,22 +8,29 @@ nice to have some alternatives packaged in Debian.)
 
 I ended up implementing this:
 
-	letsEncrypt :: AgreeTOS -> Domain -> WebRoot -> CertInstaller -> Property NoInfo
+	letsEncrypt :: AgreeTOS -> Domain -> WebRoot -> Property NoInfo
 
-The interesting part of that is the `CertInstaller`, which is passed the
-certificate files that letsencrypt generates, and is responsible for making
-the web server (or whatever) use them.
+This property just makes the certificate available, it does not configure
+the web server to use it. This avoids relying on the letsencrypt client's
+apache config munging, which is probably useful for many people, but not
+those of us using configuration management systems. And so avoids most of
+the complicated magic that the letsencrypt client has a reputation for.
 
-This avoids relying on the letsencrypt client's apache config munging,
-which is probably useful for many people, but not those of us using
-configuration management systems. And so avoids most of the complicated
-magic that the letsencrypt client has a reputation for.
-
-And, this API lets other propellor properties integrate with letsencrypt
-by providing a `CertInstaller` of their own. Like this property, which 
-sets up apache to serve a https website, using letsencrypt to get
+Instead, any property that wants to use the certificate can just
+use leteencrypt to get it and set up the server when it makes a change to
 the certificate:
 
+	letsEncrypt (LetsEncrypt.AgreeTOS (Just "me@my.domain")) "example.com" "/var/www"
+		`onChange` setupthewebserver
+
+(Took me a while to notice I could use `onChange` like that,
+and so divorce the cert generation/renewal from the server setup. 
+`onChange` is awesome! This blog post has been updated accordingly.)
+
+In practice, the http site has to be brought up first, and then
+letsencrypt run, and then the cert installed and the https site brought up
+using it. That dance is automated by this property:
+
 	Apache.httpsVirtualHost "example.com" "/var/www"
 		(LetsEncrypt.AgreeTOS (Just "me@my.domain"))
 
@@ -54,8 +61,8 @@ is not available when your certificate needs to be renewed.
 What I've done in propellor to handle renewal is, it runs letsencrypt every
 time, with the --keep-until-expiring option. If this fails, propellor will
 report a failure. As long as propellor is run periodically by a cron job,
-this should result in multiple failure reports being sent (for 30 days I think)
-before a cert expires without getting renewed. But, I have not been able
-to test this.
+this should result in multiple failure reports being sent (for 30 days I
+think) before a cert expires without getting renewed. But, I have not been
+able to test this.
 
 [[!tag propellor]]

typowq
diff --git a/blog/entry/letsencrypt_support_in_propellor.mdwn b/blog/entry/letsencrypt_support_in_propellor.mdwn
index 70f2358..2592c40 100644
--- a/blog/entry/letsencrypt_support_in_propellor.mdwn
+++ b/blog/entry/letsencrypt_support_in_propellor.mdwn
@@ -25,7 +25,7 @@ sets up apache to serve a https website, using letsencrypt to get
 the certificate:
 
 	Apache.httpsVirtualHost "example.com" "/var/www"
-		(LetsEncrypt.AgreeTos (Just "me@my.domain"))
+		(LetsEncrypt.AgreeTOS (Just "me@my.domain"))
 
 That's about as simple a configuration as I can imagine for such a website!
 

typo
diff --git a/blog/entry/letsencrypt_support_in_propellor.mdwn b/blog/entry/letsencrypt_support_in_propellor.mdwn
index e949796..70f2358 100644
--- a/blog/entry/letsencrypt_support_in_propellor.mdwn
+++ b/blog/entry/letsencrypt_support_in_propellor.mdwn
@@ -55,7 +55,7 @@ What I've done in propellor to handle renewal is, it runs letsencrypt every
 time, with the --keep-until-expiring option. If this fails, propellor will
 report a failure. As long as propellor is run periodically by a cron job,
 this should result in multiple failure reports being sent (for 30 days I think)
-before an cert expires without getting renewed. But, I have not been able
+before a cert expires without getting renewed. But, I have not been able
 to test this.
 
 [[!tag propellor]]

blog update
diff --git a/blog/entry/letsencrypt_support_in_propellor.mdwn b/blog/entry/letsencrypt_support_in_propellor.mdwn
new file mode 100644
index 0000000..e949796
--- /dev/null
+++ b/blog/entry/letsencrypt_support_in_propellor.mdwn
@@ -0,0 +1,61 @@
+I've integrated letsencrypt into propellor today. 
+
+I'm using the reference letsencrypt client. While I've seen complaints that
+it has a lot of dependencies and is too complicated, it seemed to only need
+to pull in a few packages, and use only a few megabytes of disk space, and
+it has fewer options than `ls` does. So seems fine. (Although it would be
+nice to have some alternatives packaged in Debian.)
+
+I ended up implementing this:
+
+	letsEncrypt :: AgreeTOS -> Domain -> WebRoot -> CertInstaller -> Property NoInfo
+
+The interesting part of that is the `CertInstaller`, which is passed the
+certificate files that letsencrypt generates, and is responsible for making
+the web server (or whatever) use them.
+
+This avoids relying on the letsencrypt client's apache config munging,
+which is probably useful for many people, but not those of us using
+configuration management systems. And so avoids most of the complicated
+magic that the letsencrypt client has a reputation for.
+
+And, this API lets other propellor properties integrate with letsencrypt
+by providing a `CertInstaller` of their own. Like this property, which 
+sets up apache to serve a https website, using letsencrypt to get
+the certificate:
+
+	Apache.httpsVirtualHost "example.com" "/var/www"
+		(LetsEncrypt.AgreeTos (Just "me@my.domain"))
+
+That's about as simple a configuration as I can imagine for such a website!
+
+----
+
+The two parts of letsencrypt that *are* complicated are not the fault of
+the client really. Those are renewal and rate limiting.
+
+I'm currently rate limited for the next week because I asked letsencrypt
+for several certificates for a domain, as I was learning how to use it and
+integrating it into propellor. So I've not quite managed to fully test
+everything. That's annoying. I also worry that rate limiting could hit at
+an inopportune time once I'm relying on letsencrypt. It's especially
+problimatic that it only allows 5 certs for subdomains of a given domain
+per week. What if I use a lot of subdomains?
+
+Renewal is complicated mostly because there's no good way to test it. You
+set up your cron job, or whatever, and wait three months, and hopefully it
+worked. Just as likely, you got something wrong, and your website breaks.
+Maybe letsencrypt could offer certificates that will only last an hour,
+or a day, for use when testing renewal.
+
+Also, what if something goes wrong with renewal? Perhaps letsencrypt.org
+is not available when your certificate needs to be renewed.
+
+What I've done in propellor to handle renewal is, it runs letsencrypt every
+time, with the --keep-until-expiring option. If this fails, propellor will
+report a failure. As long as propellor is run periodically by a cron job,
+this should result in multiple failure reports being sent (for 30 days I think)
+before an cert expires without getting renewed. But, I have not been able
+to test this.
+
+[[!tag propellor]]

Added a comment: congratulations
diff --git a/blog/entry/git-annex_v6/comment_1_f6a94e3ccc64b9feceb72c29d2911475._comment b/blog/entry/git-annex_v6/comment_1_f6a94e3ccc64b9feceb72c29d2911475._comment
new file mode 100644
index 0000000..7e7680c
--- /dev/null
+++ b/blog/entry/git-annex_v6/comment_1_f6a94e3ccc64b9feceb72c29d2911475._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ subject="congratulations"
+ date="2016-01-23T21:45:50Z"
+ content="""
+git annex v6 is a great idea. while i still have to use and test it, i find it admirable that you went through the trouble of evaluating a competing approach to the similar problem space, adopt and even extend it in your own project. this is the true hacker spirit at work, and while it's unfortunate that the implementation isn't directly compatible with LFS (it couldn't, since it's decentralised) or that github didn't consider using git-annex for its implementation (it's a commercial silo after all), it is great that the ideas are percolating around like this. it will hopefully make both projects better. :)
+
+thanks again for git-annex!
+"""]]

correct blog entry typo
diff --git a/blog/entry/git-annex_v6.mdwn b/blog/entry/git-annex_v6.mdwn
index ca12992..8e5527f 100644
--- a/blog/entry/git-annex_v6.mdwn
+++ b/blog/entry/git-annex_v6.mdwn
@@ -55,7 +55,7 @@ git-lfs downloads all the files in the work tree. It doesn't have
 facilities for dropping the content of some files to free up space,
 or for configuring a repository to only want to get a subset of files
 in the first place. On the other hand, git-annex has excellent support for
-alll those things, and this comes largely for free from its decentralized
+all those things, and this comes largely for free from its decentralized
 design.
 
 If git has showed us anything, it's perhaps that a little added complexity

update
diff --git a/links/interviews.mdwn b/links/interviews.mdwn
index 71c7121..5d05897 100644
--- a/links/interviews.mdwn
+++ b/links/interviews.mdwn
@@ -6,5 +6,5 @@
 [2015: Life after Debian](http://zgrimshell.github.io/posts/interviews-with-floss-developers-joey-hess.html)  
 > "I want to build worthwhile things that might last."
 
-[2016: Linux Weekly News interview](http://lwn.net/Articles/672352/)  
+[2016: Linux Weekly News](http://lwn.net/Articles/672352/)  
 > "I still see myself as a beginner, and certainly not an exemplar."

lwn interview
diff --git a/links/interviews.mdwn b/links/interviews.mdwn
index 894e877..71c7121 100644
--- a/links/interviews.mdwn
+++ b/links/interviews.mdwn
@@ -5,3 +5,6 @@
 
 [2015: Life after Debian](http://zgrimshell.github.io/posts/interviews-with-floss-developers-joey-hess.html)  
 > "I want to build worthwhile things that might last."
+
+[2016: Linux Weekly News interview](http://lwn.net/Articles/672352/)  
+> "I still see myself as a beginner, and certainly not an exemplar."

blog update
diff --git a/blog/entry/git-annex_v6.mdwn b/blog/entry/git-annex_v6.mdwn
new file mode 100644
index 0000000..ca12992
--- /dev/null
+++ b/blog/entry/git-annex_v6.mdwn
@@ -0,0 +1,98 @@
+Version 6 of git-annex, released last week, adds a major new feature;
+support for unlocked large files that can be edited as usual and committed
+using regular git commands.
+
+For example:
+
+	git init
+	git annex init --version=6
+	mv ~/foo.iso .
+	git add foo.iso
+	git commit -m "added hundreds of megabytes to git annex (not git)"
+	git remote add origin ssh://sever/dir
+	git annex sync origin --content # uploads foo.iso
+
+Compare that with how git-annex has worked from the beginning, where
+`git annex add` is used to add a file, and then the file is locked,
+preventing further modifications of it. That is still a very useful way to
+use git-annex for many kinds of files, and is still supported of course.
+Indeed, you can easily switch files back and forth between being locked and
+unlocked.
+
+This new unlocked file mode uses git's smudge/clean filters, and I was
+busy developing it all through December. It started out playing
+catch-up with [git-lfs](https://github.com/github/git-lfs) somewhat, but
+has significantly surpassed it now in several ways.
+
+So, if you had tried git-annex before, but found it didn't meet your needs, 
+you may want to [give it another look](https://git-annex.branchable.com/tips/unlocked_files/) now.
+
+-----
+
+Now a few thoughts on git-annex vs git-lfs, and different tradeoffs made by
+them.
+
+After trying it out, my feeling is that git-lfs brings an admirable
+simplicity to using git with large files. File contents are automatically
+uploaded to the server when a git branch is pushed, and downloaded when a
+branch is merged, and after setting it up, the user may not need to change
+their git workflow at all to use git-lfs.
+
+But there are some serious costs to that simplicity. git-lfs is a
+centralized system. This is especially problimatic when dealing with large
+files. Being a decentralized system, git-annex has a lot more flexability,
+like transferring large file contents peer-to-peer over a LAN, and being
+able to choose where large quantities of data are stored (maybe in S3,
+maybe on a local archive disk, etc).
+
+The price git-annex pays for this flexability is you have to configure it,
+and run some additional commands. And, it has to keep track of what content
+is located where, since it can't assume the answer is "in the central server".
+
+The simplicity of git-lfs also means that the user doesn't have much
+control over what files are present in their checkout of a repository.
+git-lfs downloads all the files in the work tree. It doesn't have
+facilities for dropping the content of some files to free up space,
+or for configuring a repository to only want to get a subset of files
+in the first place. On the other hand, git-annex has excellent support for
+alll those things, and this comes largely for free from its decentralized
+design.
+
+If git has showed us anything, it's perhaps that a little added complexity
+to support a fully distributed system won't prevent people using it. Even
+if many of them end up using it in a mostly centralized way. And that being
+decentralized can have benefits beyond the obvious ones.
+
+-----
+
+Oh yeah, one other advantage of git-annex over git-lfs. It can use half
+as much disk space!
+
+A clone of a git-lfs repository contains one copy of each file in the work
+tree. Since the user can edit that file at any time, or checking out a
+different branch can delete the file, it also stashes a copy inside
+`.git/lfs/objects/`.
+
+One of the main reasons git-annex used locked files, from the very
+beginning, was to avoid that second copy. A second local copy of a large
+file can be too expensive to put up with. When I added unlocked files in
+git-annex v6, I found it needed a second copy of them, same as git-lfs
+does. That's the default behavior. But, I decided to complicate 
+git-annex with a config setting:
+
+	git config annex.thin true
+	git annex fix
+
+Run those two commands, and now only one copy is needed for unlocked files!
+How's it work? Well, it comes down to hard links. But there is a tradeoff here,
+which is why this is not the default: When you edit a file, no local backup is
+preserved of its old content. So you have to make sure to let git-annex
+upload files to another repository before editing them or the old version
+could get lost. So it's a tradeoff, and maybe it could be improved.
+(Only thin out a file after a copy has been uploaded?)
+
+This adds a small amount of complexity to git-annex, but I feel it's well
+worth it to let unlocked files use half the disk space. If the git-lfs
+developers are reading this, that would probably be my first suggestion
+for a feature to consider adding to git-lfs. I hope for more opportunities
+to catch-up to git-lfs in turn.

update identify of someone referenced
diff --git a/svnhome.mdwn b/svnhome.mdwn
index 7890b26..9bce5de 100644
--- a/svnhome.mdwn
+++ b/svnhome.mdwn
@@ -238,8 +238,8 @@ This article, which is based on my earlier [[cvshome]] article, was
 originally published at 
 <a href="http://www.onlamp.com/pub/a/onlamp/2005/01/06/svn_homedir.html">OnLamp.com</a>.
 
-Scott Scriven uses svn for his home directory a similar way, so you
-might want to read <a href="http://toykeeper.net/tutorials/svnhome">his
+Selene Scriven uses svn for her home directory a similar way, so you
+might want to read <a href="http://toykeeper.net/tutorials/svnhome">her
 article</a> for more details and a different perspective on some things.
 
 There's a mailing list for people who use version control for their home

calendar update
diff --git a/blog/archives/2016.mdwn b/blog/archives/2016.mdwn
new file mode 100644
index 0000000..df72b76
--- /dev/null
+++ b/blog/archives/2016.mdwn
@@ -0,0 +1 @@
+[[!calendar type=year year=2016 pages="blog/entry/* and !*/Discussion"]]
diff --git a/blog/archives/2016/01.mdwn b/blog/archives/2016/01.mdwn
new file mode 100644
index 0000000..d903789
--- /dev/null
+++ b/blog/archives/2016/01.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=01 year=2016 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(01) and creation_year(2016) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2016/02.mdwn b/blog/archives/2016/02.mdwn
new file mode 100644
index 0000000..4835108
--- /dev/null
+++ b/blog/archives/2016/02.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=02 year=2016 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(02) and creation_year(2016) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2016/03.mdwn b/blog/archives/2016/03.mdwn
new file mode 100644
index 0000000..4c32245
--- /dev/null
+++ b/blog/archives/2016/03.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=03 year=2016 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(03) and creation_year(2016) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2016/04.mdwn b/blog/archives/2016/04.mdwn
new file mode 100644
index 0000000..5f1b62a
--- /dev/null
+++ b/blog/archives/2016/04.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=04 year=2016 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(04) and creation_year(2016) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2016/05.mdwn b/blog/archives/2016/05.mdwn
new file mode 100644
index 0000000..2c7c6ea
--- /dev/null
+++ b/blog/archives/2016/05.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=05 year=2016 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(05) and creation_year(2016) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2016/06.mdwn b/blog/archives/2016/06.mdwn
new file mode 100644
index 0000000..4cf8ac3
--- /dev/null
+++ b/blog/archives/2016/06.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=06 year=2016 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(06) and creation_year(2016) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2016/07.mdwn b/blog/archives/2016/07.mdwn
new file mode 100644
index 0000000..2fbcb76
--- /dev/null
+++ b/blog/archives/2016/07.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=07 year=2016 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(07) and creation_year(2016) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2016/08.mdwn b/blog/archives/2016/08.mdwn
new file mode 100644
index 0000000..970a6e7
--- /dev/null
+++ b/blog/archives/2016/08.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=08 year=2016 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(08) and creation_year(2016) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2016/09.mdwn b/blog/archives/2016/09.mdwn
new file mode 100644
index 0000000..bb038a1
--- /dev/null
+++ b/blog/archives/2016/09.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=09 year=2016 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(09) and creation_year(2016) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2016/10.mdwn b/blog/archives/2016/10.mdwn
new file mode 100644
index 0000000..2ea043a
--- /dev/null
+++ b/blog/archives/2016/10.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=10 year=2016 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(10) and creation_year(2016) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2016/11.mdwn b/blog/archives/2016/11.mdwn
new file mode 100644
index 0000000..dfff527
--- /dev/null
+++ b/blog/archives/2016/11.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=11 year=2016 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(11) and creation_year(2016) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2016/12.mdwn b/blog/archives/2016/12.mdwn
new file mode 100644
index 0000000..83f89d1
--- /dev/null
+++ b/blog/archives/2016/12.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=12 year=2016 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(12) and creation_year(2016) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]

fix url
diff --git a/code/wmbattery.mdwn b/code/wmbattery.mdwn
index d589207..c01d83e 100644
--- a/code/wmbattery.mdwn
+++ b/code/wmbattery.mdwn
@@ -24,7 +24,7 @@ some improvements in wmbattery:
 * Can make its own estimatess of time remaining or time until full charge, even if APM does not.
 
 `wmbattery` is available as a Debian package or in git
-(`git://git.kitenet.net/wmbattery`).
+(`git://git.kitenet.net/zzattic/wmbattery`).
 
 I posted some 
 [[thoughts_and_history_about_wmbattery|blog/entry/ten_years_of_free_software_--_part_7_wmbattery]]

update
diff --git a/code/realtime/design.mdwn b/code/realtime/design.mdwn
index 35689fd..208c3e9 100644
--- a/code/realtime/design.mdwn
+++ b/code/realtime/design.mdwn
@@ -162,7 +162,8 @@ How to implement this stuff? I want scenarios like:
 Crazy idea: Make having a conversation with an actor be a roguelike
 minigame. Items could represent conversational gambits, and rooms topics of
 conversation. Monsters and locked rooms would be the actor resisting your
-advances. Goal being to get to an exit that convinces the actor that you're
+advances. A pet equivilant could be the actor's growing agreement.
+Goal being to get to an exit that convinces the actor that you're
 right, or that makes the actor like you, etc.
 
 Some weapons might be logic-based, others appealing emotionally, etc.

idea
diff --git a/code/realtime/design.mdwn b/code/realtime/design.mdwn
index ba25653..35689fd 100644
--- a/code/realtime/design.mdwn
+++ b/code/realtime/design.mdwn
@@ -156,3 +156,21 @@ How to implement this stuff? I want scenarios like:
   then they'll bobble until 
   `min (B is due to unbobble next) (100 years)`, and if B is unbobbled then,
   will go out to steal from them.
+
+## conversation system
+
+Crazy idea: Make having a conversation with an actor be a roguelike
+minigame. Items could represent conversational gambits, and rooms topics of
+conversation. Monsters and locked rooms would be the actor resisting your
+advances. Goal being to get to an exit that convinces the actor that you're
+right, or that makes the actor like you, etc.
+
+Some weapons might be logic-based, others appealing emotionally, etc.
+Different monsters would be more and less affected by different kinds of
+weapons.
+
+The Qualm hits!
+You destroy the Flawed Argument with your +2 Logic!
+You trip over an emotional mine. It explodes! Movement is difficult.
+The self-forfulling prophecy grabs you. You are being crushed!
+

Added a comment: A growing trend?
diff --git a/blog/entry/dealing_with_dialup/comment_5_aa28fd5f282b29ebdd55679cc2a9e54e._comment b/blog/entry/dealing_with_dialup/comment_5_aa28fd5f282b29ebdd55679cc2a9e54e._comment
new file mode 100644
index 0000000..6385111
--- /dev/null
+++ b/blog/entry/dealing_with_dialup/comment_5_aa28fd5f282b29ebdd55679cc2a9e54e._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="yrogerg64"
+ subject="A growing trend?"
+ date="2015-12-21T05:21:53Z"
+ content="""
+I wonder if perhaps a trend is developing where users are becoming web weary and are looking for content and not fluff.  In addition to using text based browsers, I have been using Google Transcoder in FF to scrape the fluff or utilizing a user agent changer addon in FF to navigate mobile versions of some sites.  There seems to be a small but noticable resurgence of the Gopher protocol which is quite dialup friendly.  Who knows what the future brings?
+"""]]

add news item for scroll 1.20151219
diff --git a/code/scroll/news/version_1.20151219.mdwn b/code/scroll/news/version_1.20151219.mdwn
new file mode 100644
index 0000000..739a89e
--- /dev/null
+++ b/code/scroll/news/version_1.20151219.mdwn
@@ -0,0 +1,4 @@
+scroll 1.20151219 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix copyright statement; scroll is GPL2+
+   * Fix to build under ghc 7.10."""]]
\ No newline at end of file

add
diff --git a/code/pdmenu/thankyou.png b/code/pdmenu/thankyou.png
new file mode 100644
index 0000000..394f682
Binary files /dev/null and b/code/pdmenu/thankyou.png differ

fix link to deleted script
diff --git a/blog/entry/local_rsync_accelerator.mdwn b/blog/entry/local_rsync_accelerator.mdwn
index 7f88d44..78e3cb3 100644
--- a/blog/entry/local_rsync_accelerator.mdwn
+++ b/blog/entry/local_rsync_accelerator.mdwn
@@ -33,7 +33,7 @@ on a typical home NAS, with a slow (arm) CPU, the picture changes
 entirely -- now the checksum overhead is unbearable, while the IO overhead
 is minimal.
 
-So, [here's local-rsync](http://git.kitenet.net/?p=joey/home.git;a=blob_plain;f=bin/local-rsync).
+So, [here's local-rsync](http://git.kitenet.net/?p=joey/home.git;a=blob;f=bin/local-rsync;hb=0bed147834aef4efe8650d731f9160fb41b16014).
 It takes all the same options as rsync, with the caveat that
 SOURCE and DEST must be the first two options, and must be local
 directories.

add
diff --git a/code/realtime/design.mdwn b/code/realtime/design.mdwn
new file mode 100644
index 0000000..ba25653
--- /dev/null
+++ b/code/realtime/design.mdwn
@@ -0,0 +1,158 @@
+Realtime
+
+A roguelike game that's a fan-fiction/simulation of Vernor Vinge's
+_Marooned in Realtime_.
+
+## Goal
+
+Convince the bobbled remainders of humanity to unify and re-make
+a civilization.
+
+## Intro
+
+You somehow made it into a small compound, with bobble generator and
+supplies, and have just bobbled forward 100 years as the game begins, past
+the singularity. This gives you a relatively low starting tech level
+compared to many others who started nearer to that point.
+
+## Setting
+
+### Region
+
+The roguelike map should cover a relatively small region. Many bobbles have
+ended up here due to historial reasons (perhaps because the area has a
+stable geography). Around a dozen bobbles should fit on the screen.
+
+Topography: The region will often be a coastline, or contain a river, or be a
+valley in mountains. These large-scale features will be displayed in the
+region.
+
+### Compounds
+
+                          ...
+                         .....
+                        .......          ...
+                        ...@...         .....      .
+                        .......         ..@..     .@.    @
+                         .....          .....      .
+                          ...            ...
+
+Each bobble surrounds a circular compound. Or, in the case of personal
+bobble generators, a single cell. The scale within a compound is one cell
+per room. Avoids needing map generation, etc. Each room has a name
+(storeroom, kitchen, etc), and appropriate starting contents. Center room
+is always control room.
+
+### World / Universe
+
+Avoid needing to generate a full consistent world map (or more),
+but other bobbles can be located in other settings, and bobbles
+can be moved (by appropriate tech). 
+
+### Inter region movement
+
+When the user moves outside the local region, query where they're going,
+and let them try to travel there, but in an abstract, non-roguelike manner.
+For example, attempt to walk to some other known region, which may take
+months or years (game time). Or, fly to other region, which may take
+minures. Or, explore for X days looking for a region containing a lake,
+river, mountain, coast, etc.
+
+With sufficient tech, it's possible to move an entire compound, or a 
+bobble to another region. Same inter-region movement applies.
+
+Other tech (ie, self-bobbling satellites) allows telepresence across
+regions.
+
+## Time
+
+Game time is key. The game clock starts 100 years in the future from when
+the user runs the game. Bobbling can move it forward in arbitrary leaps.
+Movement within a region moves it forward in minutes or hours. Inter-region
+movement in minutes to mutiple years.
+
+Age is the most important stat. Reach old age, die, and game is over,
+win or lose. Tech can of course extend lifespans, somewhat.
+
+As years progress, regions change.
+
+* climate (ice ages, volcanic events, winding down of anthromorphic global
+  warming after the singularity, etc)
+* geologic change (mountains erode to hills, are uplifted; rivers change
+  course, dry up or widen)
+* in deep time, orbit changes, moon becomes further (IIRC), etc
+
+If someone gets stuck without a bobble generator, they're marooned in
+realtime of course. If they can last until a bobble in their region opens,
+they can hitch a ride.
+
+### Movement in time
+
+Each time a bobble is formed, its controller (the player or a actor) decides
+how long it should last. This is just an amount of time. But, more advanced
+tech allows fine-tuning this.
+
+* Examine a bobble, and you can tell when it will pop. So go forward to
+  that time.
+* When your bobble pops, tech can quickly scan for danger and re-bobble
+  forward some amount. Complex algorythms possible (go forward 2, 4, 8, or
+  more randomly).
+* Bobbled probes can be released that unbobble just before the main bobble,
+  do arbitrary analysis, and have info waiting when the main bobble pops.
+  For example, follow another compound as it pops and re-bobbles.
+* Bobble-in-bobble? I forget if the book allowed this, offensively,
+  and/or defensively.
+
+### tech
+
+Tech tree, items with abilities, seems good enough.
+
+### actors
+
+A massive part of the game.
+
+(Any way to have multiple player characters? Seems sorta doable; the game
+in multiplayer could be played turn-based, with whichever player is
+furthest back in time being able to act. When players reach the same time,
+they can interact. But, this would require other goals for other players,
+unless cooperative play makes sense. If a player decides their goal is to
+go forward until the sun explodes, they're probably kind of out of the rest
+of the game.)
+
+actors have:
+
+* A name.
+* A location.
+* An age.
+* A lifespan.
+* Control of some tech, often including a compound and bobbler.
+* A longterm goal. ("unify and re-make a civilization", 
+  "go forward until the sun explodes", 
+  "steal all the tech I can to become mighty",
+  "kill the hated others", "record and explore every hundred years", etc)
+* A shorterm goal. ("kill so-and-so", "take such-and-such", "explore region
+  for a week)")
+* Trust levels for every other actor, which change as circumstances change.
+* Value placed on every other actor, which change as circumstances change.
+  (Ie, might not trust someone much, but highly value them for whatever
+  reason.)
+* Alliances and agreements with other actors. 
+  - Deciding when to unboble together.
+  - Giving access to compound for visits.
+  - Trading/giving items.
+  - Up to and including sharing a compound with others, one of whom is
+    elected leader.
+* A satisfaction level; if things are not working well, goal may change.
+
+How to implement this stuff? I want scenarios like:
+
+* A highly values B, and trusts C. C bobbles the compund with B outside.
+  Now A distrusts C, and has a goal of overthrowing C and 
+  finding out what happened to B.
+* A trusts D. D steals from A. Now A distrusts and disvalues D and has
+  a shortterm goal (for their next N turns) of stealing from D. So,
+  A's shortterm goal makes them want to unbobble when D does.
+  If A's longterm goal is "record and explore every hundred years",
+  then they'll bobble until 
+  `min (B is due to unbobble next) (100 years)`, and if B is unbobbled then,
+  will go out to steal from them.

comment
diff --git a/blog/entry/please_build_a_haskell_to_perl_compiler/comment_3_89a0f1a421e98ef11acd625706c2e08b._comment b/blog/entry/please_build_a_haskell_to_perl_compiler/comment_3_89a0f1a421e98ef11acd625706c2e08b._comment
new file mode 100644
index 0000000..717774f
--- /dev/null
+++ b/blog/entry/please_build_a_haskell_to_perl_compiler/comment_3_89a0f1a421e98ef11acd625706c2e08b._comment
@@ -0,0 +1,43 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2015-12-13T20:11:58Z"
+ content="""
+Here's an attempt at manually compiling this haskell code:
+
+	main = let s = f 'a' in putStr s
+	  where f d = d : f d
+
+As perl:
+
+	sub f ($) {
+	        my $d=shift;
+	        mkList($d, thunk(\&f,$d)); # d : f d
+	}
+	my $s = thunk(\&f,'a');
+	force(putStr($s);
+	
+	# IO monad would make actual implementation be in terms of (>>=),
+	# since putStr (h:t) = putChar h >>= \_ -> putStr t
+	# but, we can fake it like this:
+	sub putStr ($) {
+        	my $l=force(shift());
+	        print headList($l);
+	        thunk(\&putStr, tailList($l));
+	}
+
+I think that's fairly similarly to how Fay works, although it's been
+a while since I looked at Fay. 
+
+The use of thunk() gets us laziness. The implementation of force() needs
+some trickiness to avoid blowing the perl stack (perhaps using goto),
+since it may need to repeatedly force a thunk that yields a thunk,
+as happens with "force(putStrLn($s))".
+
+Perl's GC can't handle cyclic data structures (can javascript's?).
+In f(), $d captures the input value, and it will remain
+referenced until the returned list is freed. But, there's no cyclic data
+structure at the perl level, just a list object consisting of $d and a
+thunk (which consists of a reference to f() and $d). So, I think perl's GC can
+handle that.
+"""]]

add news item for filters 2.55
diff --git a/code/filters/news/version_2.49.mdwn b/code/filters/news/version_2.49.mdwn
deleted file mode 100644
index e1fb03c..0000000
--- a/code/filters/news/version_2.49.mdwn
+++ /dev/null
@@ -1,4 +0,0 @@
-filters 2.49 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * scottish: Fix typo. Closes: #[688905](http://bugs.debian.org/688905)
-   * lolcat: New filter."""]]
\ No newline at end of file
diff --git a/code/filters/news/version_2.55.mdwn b/code/filters/news/version_2.55.mdwn
new file mode 100644
index 0000000..b1e6905
--- /dev/null
+++ b/code/filters/news/version_2.55.mdwn
@@ -0,0 +1,8 @@
+filters 2.55 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix build warnings.
+     Thanks, Marius Gavrilescu.
+   * scramble: Fix missing free and improve error handling.
+     Thanks, Marius Gavrilescu
+   * A few other minor fixes.
+   * Update urls."""]]
\ No newline at end of file

add
diff --git a/blog.mdwn b/blog.mdwn
index 46bb66a..c3c8d8f 100644
--- a/blog.mdwn
+++ b/blog.mdwn
@@ -10,7 +10,7 @@ actions=yes]]
 <a href="http://flattr.com/thing/39887/Joey-Hesss-blog" target="_blank">
 <img src="https://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this" border="0" /></a>
 
-[[!img pics/shuttleworth.jpg size=150x]]
+[[!img pics/shuttleworth.jpg size=150x link=shuttleworth-flash-grant]]
 
 [[!calendar pages="blog/entry/* and !blog/entry/*/* and !*/Discussion"]]
 
diff --git a/shuttleworth-flash-grant.mdwn b/shuttleworth-flash-grant.mdwn
new file mode 100644
index 0000000..db48bd2
--- /dev/null
+++ b/shuttleworth-flash-grant.mdwn
@@ -0,0 +1,3 @@
+In November 2015 I received a
+[Flash Grant](https://shuttleworthfoundation.org/flashgrants/)
+from the ShuttleWorth foundation.

reog
diff --git a/blog.mdwn b/blog.mdwn
index 19cdffa..46bb66a 100644
--- a/blog.mdwn
+++ b/blog.mdwn
@@ -10,6 +10,8 @@ actions=yes]]
 <a href="http://flattr.com/thing/39887/Joey-Hesss-blog" target="_blank">
 <img src="https://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this" border="0" /></a>
 
+[[!img pics/shuttleworth.jpg size=150x]]
+
 [[!calendar pages="blog/entry/* and !blog/entry/*/* and !*/Discussion"]]
 
 [[!calendar pages="blog/entry/* and !blog/entry/*/* and !*/Discussion" year=-1]]
@@ -40,6 +42,4 @@ Other feeds:
 Recent [chatter](https://identi.ca/joeyh):
 [[!inline pages="internal(grep/identi.ca_posts/*)" template="microblog" show=5 feeds=no]]
 
-[[!img pics/shuttleworth.jpg size=150x]]
-
 """]]

larger
diff --git a/blog.mdwn b/blog.mdwn
index 666a01e..19cdffa 100644
--- a/blog.mdwn
+++ b/blog.mdwn
@@ -40,6 +40,6 @@ Other feeds:
 Recent [chatter](https://identi.ca/joeyh):
 [[!inline pages="internal(grep/identi.ca_posts/*)" template="microblog" show=5 feeds=no]]
 
-[[!img pics/shuttleworth.jpg size=100x]]
+[[!img pics/shuttleworth.jpg size=150x]]
 
 """]]

add
diff --git a/blog.mdwn b/blog.mdwn
index ed4c232..666a01e 100644
--- a/blog.mdwn
+++ b/blog.mdwn
@@ -40,4 +40,6 @@ Other feeds:
 Recent [chatter](https://identi.ca/joeyh):
 [[!inline pages="internal(grep/identi.ca_posts/*)" template="microblog" show=5 feeds=no]]
 
+[[!img pics/shuttleworth.jpg size=100x]]
+
 """]]
diff --git a/blog/pics/shuttleworth.jpg b/blog/pics/shuttleworth.jpg
new file mode 100644
index 0000000..33a2b2b
Binary files /dev/null and b/blog/pics/shuttleworth.jpg differ

poll vote (too long for me)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index 08c9033..543b3af 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" 3 "too long for me" 15 "too haskell for me" 12 "not interested"]]
+[[!poll 45 "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]]

Add question about using it for external directories
diff --git a/code/etckeeper/discussion.mdwn b/code/etckeeper/discussion.mdwn
index e1d111f..7e9d21a 100644
--- a/code/etckeeper/discussion.mdwn
+++ b/code/etckeeper/discussion.mdwn
@@ -244,3 +244,7 @@ I looked at the post-invoke hook that etckeeper puts in /etc/apt/apt.conf.d, but
 ---
 
 There is some odd behavior when doing a rebase with a reword. The .etckeeper file gets conflicts (could be because of http://git.661346.n2.nabble.com/rebase-i-reword-runs-pre-commit-hook-with-curious-results-td7244648.html). This is easy to work-around with a manual `etckeeper pre-commit` before `git rebase --continue` but I wonder if the pre-commit hook can be modified to make this work seamlessly?
+
+---
+I would like to use awesome etckeeper not only for /etc, but also for tracking python code at /usr/lib/python2.7/dist-packages/. In my specific situation people sometimes log in to servers and change code there on the fly. Should I just add one line 'etckeeper commit -d /usr/lib/python2.7/dist-packages/ "daily autocommit" >/dev/null' in cron job here https://github.com/joeyh/etckeeper/blob/master/debian/cron.daily#L15 ? What else should I think about when using etckeeper for two dirs?
+

update
diff --git a/code/concurrent-output.mdwn b/code/concurrent-output.mdwn
index 26b6c9b..dee5240 100644
--- a/code/concurrent-output.mdwn
+++ b/code/concurrent-output.mdwn
@@ -1,19 +1,14 @@
 Haskell library to let multiple threads and external processes
 concurrently output to the console, without it getting all garbled up.
 
-[concurrent-output](http://hackage.haskell.org/package/concurrent-output)
-
-Provides a simple interface for writing concurrent programs that
-need to output a lot of status messages to the console, or display
-multiple progress bars for different activities at the same time,
-or concurrently run external commands that output to the console.
-
 Built on top of that is a way of defining multiple output regions,
 which are automatically laid out on the screen and can be individually
-updated. Can be used for progress displays etc.
+updated by concurrent threads. Can be used for progress displays etc.
+
+[concurrent-output on Hackage](http://hackage.haskell.org/package/concurrent-output)
 
 [[demo2.gif]]
 
 [[aptdemo.gif]]
 
-Used by: [[git-annex]] [[propellor]]
+Used by: [[git-annex]] [[propellor]] [etc](http://packdeps.haskellers.com/reverse/concurrent-output)

Suppress sponge warnings for stdout?
diff --git a/code/moreutils/discussion.mdwn b/code/moreutils/discussion.mdwn
index 22f7279..d98c4ee 100644
--- a/code/moreutils/discussion.mdwn
+++ b/code/moreutils/discussion.mdwn
@@ -475,3 +475,26 @@ would break into a different cluster whenever the time from one line to the next
 It would be nice to show both stdin and stderr, and distinguish them.  (Otherwise one needs 2>&1 to combine stdin and stderr.)  But that could alternatively be done with a colorizer, which would be a good separate tool to have.
 
 I'd like to have environment variable TS_FORMAT to avoid typing custom format every time I use ts. Default is very inconvenient to read for non-native english speaker; I personally almost always use '%H:%M:%S'.
+
+## Suppress sponge warnings for stdout?
+
+I have the following two scripts:
+
+*foo.py*:
+
+    #!/usr/bin/env python
+
+    import subprocess
+    subprocess.call(("bar.sh"))
+
+*bar.sh*:
+
+    #!/bin/bash
+
+    cat /usr/share/dict/words | sponge | less
+
+Running foo.py and then immediately exiting 'less' by pressing 'q' causes sponge to print an error:
+
+    error writing buffer to output file: Broken pipe
+
+Curiously, running bar.sh directly doesn't have this problem.  I'm not sure what Python is doing to the execution environment to cause this, but would you consider changing write_buff_out to suppress its warning spew if it's writing to stdout?

update
diff --git a/code/concurrent-output/discussion.mdwn b/code/concurrent-output/discussion.mdwn
index 897a4cc..57df5fb 100644
--- a/code/concurrent-output/discussion.mdwn
+++ b/code/concurrent-output/discussion.mdwn
@@ -4,3 +4,6 @@ Hm... this doesn't appear to work on OSX (in iTerm, at least). I wonder what's g
 > sequences for cursor movement. I've tested it on several terminals on
 > Linux, but have no access to OSX. It also works on Windows due to the
 > portability layer in ansi-terminal. --[[Joey]]
+
+> > Version 1.6.1 avoids using some ANSI codes that are not widely
+> > supported, and I think will work on OSX. --[[Joey]]

response
diff --git a/code/concurrent-output/discussion.mdwn b/code/concurrent-output/discussion.mdwn
index 660331f..897a4cc 100644
--- a/code/concurrent-output/discussion.mdwn
+++ b/code/concurrent-output/discussion.mdwn
@@ -1 +1,6 @@
 Hm... this doesn't appear to work on OSX (in iTerm, at least). I wonder what's going on.
+
+> concurrent-output should work on terminals that support ANSI escape
+> sequences for cursor movement. I've tested it on several terminals on
+> Linux, but have no access to OSX. It also works on Windows due to the
+> portability layer in ansi-terminal. --[[Joey]]

diff --git a/code/concurrent-output/discussion.mdwn b/code/concurrent-output/discussion.mdwn
new file mode 100644
index 0000000..660331f
--- /dev/null
+++ b/code/concurrent-output/discussion.mdwn
@@ -0,0 +1 @@
+Hm... this doesn't appear to work on OSX (in iTerm, at least). I wonder what's going on.

update
diff --git a/code/concurrent-output.mdwn b/code/concurrent-output.mdwn
index 7cc2095..26b6c9b 100644
--- a/code/concurrent-output.mdwn
+++ b/code/concurrent-output.mdwn
@@ -15,3 +15,5 @@ updated. Can be used for progress displays etc.
 [[demo2.gif]]
 
 [[aptdemo.gif]]
+
+Used by: [[git-annex]] [[propellor]]

hmm
diff --git a/blog/entry/STM_Region_contents/comment_3_de694db1218a83dcf6430c90e6502fd9._comment b/blog/entry/STM_Region_contents/comment_3_de694db1218a83dcf6430c90e6502fd9._comment
index 4b0d19e..51b59b9 100644
--- a/blog/entry/STM_Region_contents/comment_3_de694db1218a83dcf6430c90e6502fd9._comment
+++ b/blog/entry/STM_Region_contents/comment_3_de694db1218a83dcf6430c90e6502fd9._comment
@@ -25,5 +25,8 @@ Implementation of that approach using console-regions:
 		writeTVar counter 0
 		return todisplay
 
-Well, that's 10% of the LoC budget gone. ;)
+Edit: Hmm, looking at that, it doesn't quite work. Since the STM transaction
+reads from the counter and then modifies it, when concurrent-output asks STM
+to `retry` in order to wait for changes, it will immediately re-run the
+action, since a value it looked at has changed. So, dunno..
 """]]

mv
diff --git a/blog/entry/STM_Region_contents/comment_1_de694db1218a83dcf6430c90e6502fd9._comment b/blog/entry/STM_Region_contents/comment_1_de694db1218a83dcf6430c90e6502fd9._comment
deleted file mode 100644
index 4b0d19e..0000000
--- a/blog/entry/STM_Region_contents/comment_1_de694db1218a83dcf6430c90e6502fd9._comment
+++ /dev/null
@@ -1,29 +0,0 @@
-[[!comment format=mdwn
- username="joey"
- subject="""comment 1"""
- date="2015-11-04T15:20:55Z"
- content="""
-Recursion would indeed be where something so simple becomes problimatic.
-
-One way to limit iterations would be to make a cell have a counter. When
-the cell calculates its value, it increments the counter and bails if
-there's been too much calculation. The counter is reset to 0 once the cell
-is successfully displayed.
-
-Implementation of that approach using console-regions:
-
-	cell <- newConsoleRegion
-	counter <- newTVar 0
-	setConsoleRegion cell = do
-		n <- readTVar counter
-		if n > 100
-			then return "ERROR" -- or the current value or whatever
-			else do
-				modifyTVar' counter (+)
-				-- look at other cells here
-	tuneDisplay cell $ \todisplay -> do
-		writeTVar counter 0
-		return todisplay
-
-Well, that's 10% of the LoC budget gone. ;)
-"""]]
diff --git a/blog/entry/STM_Region_contents/comment_3_de694db1218a83dcf6430c90e6502fd9._comment b/blog/entry/STM_Region_contents/comment_3_de694db1218a83dcf6430c90e6502fd9._comment
new file mode 100644
index 0000000..4b0d19e
--- /dev/null
+++ b/blog/entry/STM_Region_contents/comment_3_de694db1218a83dcf6430c90e6502fd9._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2015-11-04T15:20:55Z"
+ content="""
+Recursion would indeed be where something so simple becomes problimatic.
+
+One way to limit iterations would be to make a cell have a counter. When
+the cell calculates its value, it increments the counter and bails if
+there's been too much calculation. The counter is reset to 0 once the cell
+is successfully displayed.
+
+Implementation of that approach using console-regions:
+
+	cell <- newConsoleRegion
+	counter <- newTVar 0
+	setConsoleRegion cell = do
+		n <- readTVar counter
+		if n > 100
+			then return "ERROR" -- or the current value or whatever
+			else do
+				modifyTVar' counter (+)
+				-- look at other cells here
+	tuneDisplay cell $ \todisplay -> do
+		writeTVar counter 0
+		return todisplay
+
+Well, that's 10% of the LoC budget gone. ;)
+"""]]

response
diff --git a/blog/entry/STM_Region_contents/comment_1_de694db1218a83dcf6430c90e6502fd9._comment b/blog/entry/STM_Region_contents/comment_1_de694db1218a83dcf6430c90e6502fd9._comment
new file mode 100644
index 0000000..4b0d19e
--- /dev/null
+++ b/blog/entry/STM_Region_contents/comment_1_de694db1218a83dcf6430c90e6502fd9._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2015-11-04T15:20:55Z"
+ content="""
+Recursion would indeed be where something so simple becomes problimatic.
+
+One way to limit iterations would be to make a cell have a counter. When
+the cell calculates its value, it increments the counter and bails if
+there's been too much calculation. The counter is reset to 0 once the cell
+is successfully displayed.
+
+Implementation of that approach using console-regions:
+
+	cell <- newConsoleRegion
+	counter <- newTVar 0
+	setConsoleRegion cell = do
+		n <- readTVar counter
+		if n > 100
+			then return "ERROR" -- or the current value or whatever
+			else do
+				modifyTVar' counter (+)
+				-- look at other cells here
+	tuneDisplay cell $ \todisplay -> do
+		writeTVar counter 0
+		return todisplay
+
+Well, that's 10% of the LoC budget gone. ;)
+"""]]

Added a comment
diff --git a/blog/entry/STM_Region_contents/comment_2_85e8f64fe21e8504f967922208f69b3e._comment b/blog/entry/STM_Region_contents/comment_2_85e8f64fe21e8504f967922208f69b3e._comment
new file mode 100644
index 0000000..aec6b76
--- /dev/null
+++ b/blog/entry/STM_Region_contents/comment_2_85e8f64fe21e8504f967922208f69b3e._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="Jon"
+ subject="comment 2"
+ date="2015-11-04T11:39:14Z"
+ content="""
+Very cool. Reading you and Joachim having so much fun with Haskell encourages me to spend more time with it myself.
+"""]]

Added a comment: What about cycles?
diff --git a/blog/entry/STM_Region_contents/comment_1_031cf421abb823729e323458f97d658f._comment b/blog/entry/STM_Region_contents/comment_1_031cf421abb823729e323458f97d658f._comment
new file mode 100644
index 0000000..bfe9026
--- /dev/null
+++ b/blog/entry/STM_Region_contents/comment_1_031cf421abb823729e323458f97d658f._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="wjt"
+ subject="What about cycles?"
+ date="2015-11-04T09:47:04Z"
+ content="""
+Spreadsheets support mutual recursion between cells, calculating up to *n* iterations or until values change by no more than *δ*, whichever comes first (as I understand it). Supporting this (or even failing gracefully) might make your spreadsheet grow to more than 100 lines. Would be interesting to see!
+"""]]

blog update
diff --git a/blog/entry/STM_Region_contents.mdwn b/blog/entry/STM_Region_contents.mdwn
new file mode 100644
index 0000000..6d570f1
--- /dev/null
+++ b/blog/entry/STM_Region_contents.mdwn
@@ -0,0 +1,59 @@
+[[code/concurrent-output]] released yesterday got a lot of fun features.
+It now does full curses-style minimization of the output, to redraw updated
+lines with optimal efficiency. And supports multiline regions/wrapping too
+long lines. And allows the user to embed ANSI colors in a region. 
+3 features that are in some tension and were fun to implement all
+together.
+
+But I have a more interesting feature to blog about...
+I've added the ability for the content of a Region to be determined by
+a ([STM transaction](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCMQFjAAahUKEwi_5rOt2_TIAhXIWz4KHbKVDso&url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FSoftware_transactional_memory&usg=AFQjCNFARSOmrLRRV3seFUYdAwqLSb1gtQ&sig2=m14-7kjcYLGh0H6z4qDB3A)).
+
+Here, for example, is a region that's a clock:
+
+[[!format haskell """
+timeDisplay :: TVar UTCTime -> STM Text
+timeDisplay tv = T.pack . show <$> readTVar tv
+
+clockRegion :: IO ConsoleRegionHandle
+clockRegion = do
+	tv <- atomically . newTVar =<< getCurrentTime
+	r <- openConsoleRegion Linear
+	setConsoleRegion r (timeDisplay tv)
+	async $ forever $ do
+		threadDelay 1000000 -- 1 sec
+		atomically . (writeTVar tv) =<< getCurrentTime
+	return r
+"""]]
+
+There's something magical about this. Whenever a new value is written
+into the TVar, concurrent-output automatically knows that this region needs
+to be updated. How does it know how to do that? 
+
+Magic of STM. Basically, concurrent-output composes all the STM transactions of
+Regions, and asks STM to wait until there's something new to display. STM keeps
+track of whatever TVars might be looked at, and so can put the display thread
+to sleep until there's a change to display.
+
+Using STM I've gotten extensability for free, due to the nice ways that STM
+transactions compose.
+
+A few other obvious things to do with this: Compose 2 regions with padding
+so they display on the same line, left and right aligned. Trim a region's
+content to the display width. (Handily exported by concurrent-output
+in a TVar for this kind of thing.)
+
+----
+
+I'm tempted to write a console spreadsheet using this. Each 
+visible cell of the spreadsheet would have its own region, that uses a STM
+transaction to display. Plain data Cells would just display their current
+value. Cells that contain a function would read the current values of
+other Cells, and use that to calculate what to display. Which means that
+a Cell containing a function would automatically update whenever any of
+the Cells that it depends on were updated!
+
+Do you think that a simple interactive spreadsheet built this way
+would be more than 100 lines of code?
+
+[[!tag haskell]]

Added a comment: The APT-like output…
diff --git a/blog/entry/a_tiling_region_manager_for_the_console/comment_1_1695fe93d884a31604f6484a076f5910._comment b/blog/entry/a_tiling_region_manager_for_the_console/comment_1_1695fe93d884a31604f6484a076f5910._comment
new file mode 100644
index 0000000..40920a4
--- /dev/null
+++ b/blog/entry/a_tiling_region_manager_for_the_console/comment_1_1695fe93d884a31604f6484a076f5910._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://mirsolutions.de/"
+ nickname="mirabilos"
+ subject="The APT-like output…"
+ date="2015-11-02T14:14:19Z"
+ content="""
+… is not entirely realistic: it doesn’t say “Waiting for headers” followed by just stalling… ;)
+"""]]

Added a comment
diff --git a/blog/entry/concurrent_output_library/comment_3_23aa4b524cd753057c5d60bbd76be202._comment b/blog/entry/concurrent_output_library/comment_3_23aa4b524cd753057c5d60bbd76be202._comment
new file mode 100644
index 0000000..a71dfa3
--- /dev/null
+++ b/blog/entry/concurrent_output_library/comment_3_23aa4b524cd753057c5d60bbd76be202._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="comment 3"
+ date="2015-10-31T17:31:56Z"
+ content="""
+JFTR, Joey and I discussed this offline, and decided that I will deprecate my library in favor of his, once I suggestively convinced him to add some of the features that I had in my library.
+"""]]

blog update
diff --git a/blog/entry/a_tiling_region_manager_for_the_console.mdwn b/blog/entry/a_tiling_region_manager_for_the_console.mdwn
new file mode 100644
index 0000000..3a5a2b1
--- /dev/null
+++ b/blog/entry/a_tiling_region_manager_for_the_console.mdwn
@@ -0,0 +1,88 @@
+Building on top of [[code/concurrent-output]], and some related work
+Joachim Breitner did earlier, I now have a kind of equivilant to a tiling
+window manager, except it's managing regions of the console for different
+parts of a single program.
+
+Here's a really silly demo, in an animated gif:
+
+[[code/concurrent-output/demo2.gif]]
+
+Not bad for 23 lines of code, is that? Seems much less tedious to do things
+this way than using ncurses. Even with its panels, ncurses requires you to
+think about layout of various things on the screen, and many low-level
+details. This, by contrast, is compositional, just add another region and a
+thread to update it, and away it goes. 
+
+So, here's an apt-like download progress display, in 30 lines of code.
+
+[[code/concurrent-output/aptdemo.gif]]
+
+Not only does it have regions which are individual lines of the screen,
+but those can have sub-regions within them as seen here (and so on).
+
+And, log-type messages automatically scroll up above the regions.
+External programs run by `createProcessConcurrent` will automatically
+get their output/errors displayed there, too.
+
+What I'm working on now is support for multiline regions, which
+automatically grow/shrink to fit what's placed in them. The hard part,
+which I'm putting the finishing touches on, is to accurately work out how
+large a region is before displaying it, in order to lay it out. Requires
+parsing ANSI codes amoung other things.
+
+## STM rules
+
+There's so much concurrency, with complicated interrelated data being
+updated by different threads, that I couldn't have possibly built this
+without Software Transactional Memory. 
+
+Rather than a nightmare of locks behind locks behind locks, the result is so
+well behaved that I'm confident that anyone who needs more control over the
+region layout, or wants to do funky things can dive into to the STM interface
+and update the data structures, and nothing will ever deadlock or be
+inconsistent, and as soon as an update completes, it'll display on-screen.
+
+An example of how powerful and beuatiful STM is, here's how the main
+display thread determines when it needs to refresh the display:
+
+[[!format haskell """
+data DisplayChange
+        = BufferChange [(StdHandle, OutputBuffer)]
+        | RegionChange RegionSnapshot
+        | TerminalResize (Maybe Width)
+        | EndSignal ()
+
+	...
+                change <- atomically $
+                        (RegionChange <$> regionWaiter origsnapshot)
+                                `orElse`
+                        (RegionChange <$> regionListWaiter origsnapshot)
+                                `orElse`
+                        (BufferChange <$> outputBufferWaiterSTM waitCompleteLines)
+                                `orElse`
+                        (TerminalResize <$> waitwidthchange)
+                                `orElse`
+                        (EndSignal <$> waitTSem endsignal)
+                case change of
+                        RegionChange snapshot -> do
+				...
+                        BufferChange buffers -> do
+				...
+                        TerminalResize width -> do
+				...
+"""]]
+
+So, it composes all these STM actions that can wait on various kinds of
+changes, to get one big action, that waits for all of the above, and builds
+up a nice sum type to represent what's changed.
+
+Another example is that the whole support for sub-regions only involved
+adding 30 lines of code, all of it using STM, and it worked 100% the first
+time.
+
+----
+
+Available in concurrent-output 1.1.0.
+
+[[!tag haskell]]
+[[!tag code/concurrent-output]]

add
diff --git a/code/concurrent-output.mdwn b/code/concurrent-output.mdwn
index 8209909..7cc2095 100644
--- a/code/concurrent-output.mdwn
+++ b/code/concurrent-output.mdwn
@@ -13,3 +13,5 @@ which are automatically laid out on the screen and can be individually
 updated. Can be used for progress displays etc.
 
 [[demo2.gif]]
+
+[[aptdemo.gif]]
diff --git a/code/concurrent-output/aptdemo.gif b/code/concurrent-output/aptdemo.gif
new file mode 100644
index 0000000..0be0798
Binary files /dev/null and b/code/concurrent-output/aptdemo.gif differ

demo
diff --git a/code/concurrent-output.mdwn b/code/concurrent-output.mdwn
index c33584b..8209909 100644
--- a/code/concurrent-output.mdwn
+++ b/code/concurrent-output.mdwn
@@ -11,3 +11,5 @@ or concurrently run external commands that output to the console.
 Built on top of that is a way of defining multiple output regions,
 which are automatically laid out on the screen and can be individually
 updated. Can be used for progress displays etc.
+
+[[demo2.gif]]
diff --git a/code/concurrent-output/demo2.gif b/code/concurrent-output/demo2.gif
new file mode 100644
index 0000000..7c3da09
Binary files /dev/null and b/code/concurrent-output/demo2.gif differ

add page for concurrent-output
diff --git a/blog/entry/concurrent_output_library.mdwn b/blog/entry/concurrent_output_library.mdwn
index 6e859ba..27d1e30 100644
--- a/blog/entry/concurrent_output_library.mdwn
+++ b/blog/entry/concurrent_output_library.mdwn
@@ -101,3 +101,4 @@ It seems to work pretty great though. I got Propellor using it,
 and Propellor can now run actions concurrently!
 
 [[!tag haskell]]
+[[!tag code/concurrent-output]]
diff --git a/code.mdwn b/code.mdwn
index bc27bf6..be531de 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -7,6 +7,7 @@ The stuff that's swapped into my local cache at the moment.
 
 [[git-annex]]
 [[propellor]]
+[[concurrent-output]]
 [[myrepos|mr]]
 [[etckeeper]]
 [[ikiwiki]]
@@ -14,6 +15,7 @@ The stuff that's swapped into my local cache at the moment.
 [[ikiwiki-hosting]]
 [[github-backup]]
 [[shell-monad]]
+[[brainfuck-monad]]
 
 ## Less active projects
 
@@ -24,7 +26,6 @@ In maintenance mode mostly, but I still have my hands in it somewhat.
 [[pdmenu]]
 [[filters]]
 [[electrum-mnemonic]]
-[[brainfuck-monad]]
 [[scroll]]
 
 ## Past projects
diff --git a/code/concurrent-output.mdwn b/code/concurrent-output.mdwn
new file mode 100644
index 0000000..c33584b
--- /dev/null
+++ b/code/concurrent-output.mdwn
@@ -0,0 +1,13 @@
+Haskell library to let multiple threads and external processes
+concurrently output to the console, without it getting all garbled up.
+
+[concurrent-output](http://hackage.haskell.org/package/concurrent-output)
+
+Provides a simple interface for writing concurrent programs that
+need to output a lot of status messages to the console, or display
+multiple progress bars for different activities at the same time,
+or concurrently run external commands that output to the console.
+
+Built on top of that is a way of defining multiple output regions,
+which are automatically laid out on the screen and can be individually
+updated. Can be used for progress displays etc.

module name change
diff --git a/blog/entry/concurrent_output_library.mdwn b/blog/entry/concurrent_output_library.mdwn
index b4d6162..6e859ba 100644
--- a/blog/entry/concurrent_output_library.mdwn
+++ b/blog/entry/concurrent_output_library.mdwn
@@ -65,7 +65,8 @@ some function called by main to set it up:
 
 [[!format haskell """
 import Control.Concurrent.Async
-import Control.Concurrent.Output
+import System.Console.Concurrent
+import System.Process
 
 main = withConcurrentOutput $
 	outputConcurrent "washed the car\n"

repo
diff --git a/blog/entry/concurrent_output_library/comment_2_3700f276cf3382bbfe0f5ef8e79f0e40._comment b/blog/entry/concurrent_output_library/comment_2_3700f276cf3382bbfe0f5ef8e79f0e40._comment
new file mode 100644
index 0000000..fff6aa7
--- /dev/null
+++ b/blog/entry/concurrent_output_library/comment_2_3700f276cf3382bbfe0f5ef8e79f0e40._comment
@@ -0,0 +1,49 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2015-10-29T15:11:10Z"
+ content="""
+Rats, I missed your library, and this is despite having searched hackage
+for "concurrent". It seems that search doesn't list your library on the
+first page. Hackage is just too big! ;)
+
+Seems that your library doesn't handle displaying the output of external
+commands though, does it? Such output is often multi-line, and if I
+understand how it works, your `getConcurrentOutputter` gives each caller
+a unique line that can be updated, but then it can't scroll multiline
+output of commands.
+
+I'm also particularly attached to how concurrent-output's
+`createProcessConcurrent` falls back to good old serial behavior of running
+the command with full access to the display, as long as it's the first one.
+At least this makes a lot of sense the way that propellor runs external
+commands, like apt-get update, and wants to let them display as-is when
+it's not being concurrent, but still be capable of being run concurrently
+if desired.
+
+So, I think I didn't actually do much if any duplicate work, despite not
+knowing about your library, they are solving 2 different parts of the same
+problem. What I wonder, Re library proliferation:
+
+* Would it makes sense to merge them into one library?
+* Can hackage trustees delete an unused library from it entirely?
+  (A deprecation pointer is of course possible.)
+
+Thinking about how a merged library could work, a first pass would be to
+just merge the two, and then prevent `getConcurrentOutputter` from
+outputting anything when a `createProcessConcurrent` was running and
+vice-versa. Which seems doable, concurrent-output contains locking for
+situations like this.
+
+Going further in a merge, it might be nice to support buffered output lines
+being displayed while `getConcurrentOutputter` is running, sort of like how
+apt scrolls logs up the screen while updating its progress bars at the
+bottm. This might need more screen control than it currently exersises,
+but it certianly seems doable.
+
+(Speaking of progress bars,
+<http://hackage.haskell.org/package/ascii-progress> does very similar
+things to concurrentoutput, except focused on progress bars. I've been
+wanting to use it in git-annex, but it lacks the "scroll output up the
+screen at the same time" feature.)
+"""]]

Added a comment: concurrentoutput
diff --git a/blog/entry/concurrent_output_library/comment_1_345b6055fae69ee3bb9d02714070c738._comment b/blog/entry/concurrent_output_library/comment_1_345b6055fae69ee3bb9d02714070c738._comment
new file mode 100644
index 0000000..e596142
--- /dev/null
+++ b/blog/entry/concurrent_output_library/comment_1_345b6055fae69ee3bb9d02714070c738._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="concurrentoutput"
+ date="2015-10-29T08:25:52Z"
+ content="""
+Hi Joey,
+
+did you see my very very similarly named library `concurrentoutput`, which tries to solve the same problem: http://hackage.haskell.org/package/concurrentoutput
+ 
+It provides a bit more, in that it will also write partial lines from multiple threads on their own lines, appending them as new characters come in. E.g. you can have
+
+    Building bar...done
+    Building foo...
+    Building baz...
+
+and then a bit later
+
+    Building bar...done
+    Building foo...done
+    Building baz...
+
+It’s surely not perfect, but maybe it would make sense to avoid library proliferation here?
+"""]]

format
diff --git a/blog/entry/concurrent_output_library.mdwn b/blog/entry/concurrent_output_library.mdwn
index 794e51b..b4d6162 100644
--- a/blog/entry/concurrent_output_library.mdwn
+++ b/blog/entry/concurrent_output_library.mdwn
@@ -39,9 +39,9 @@ concurrent program risks ending up with a not-so-simple program.
 So, I wanted an library with basically 2 functions:
 
 [[!format haskell """
-	outputConcurrent :: String -> IO ()
+outputConcurrent :: String -> IO ()
 	
-	createProcessConcurrent :: CreateProcess -> IO whatever
+createProcessConcurrent :: CreateProcess -> IO whatever
 """]]
 
 The idea is, you make your program use `outputConcurrent` to display
@@ -64,15 +64,15 @@ And that should be pretty much the whole API, although it's ok if it needs
 some function called by main to set it up:
 
 [[!format haskell """
-	import Control.Concurrent.Async
-	import Control.Concurrent.Output
-
-	main = withConcurrentOutput $
-		outputConcurrent "washed the car\n"
-			`concurrently`
-		createProcessConcurrent (proc "ls" [])
-			`concurrently`
-		outputConcurrent "walked the dog\n"
+import Control.Concurrent.Async
+import Control.Concurrent.Output
+
+main = withConcurrentOutput $
+	outputConcurrent "washed the car\n"
+		`concurrently`
+	createProcessConcurrent (proc "ls" [])
+		`concurrently`
+	outputConcurrent "walked the dog\n"
 """]]
 
 	$ ./demo

format
diff --git a/blog/entry/concurrent_output_library.mdwn b/blog/entry/concurrent_output_library.mdwn
index d5e27bc..794e51b 100644
--- a/blog/entry/concurrent_output_library.mdwn
+++ b/blog/entry/concurrent_output_library.mdwn
@@ -40,6 +40,7 @@ So, I wanted an library with basically 2 functions:
 
 [[!format haskell """
 	outputConcurrent :: String -> IO ()
+	
 	createProcessConcurrent :: CreateProcess -> IO whatever
 """]]
 

blog update
diff --git a/blog/entry/concurrent_output_library.mdwn b/blog/entry/concurrent_output_library.mdwn
new file mode 100644
index 0000000..d5e27bc
--- /dev/null
+++ b/blog/entry/concurrent_output_library.mdwn
@@ -0,0 +1,101 @@
+[concurrent-output](http://hackage.haskell.org/package/concurrent-output/)
+is a Haskell library I've developed this week, to make it easier to write
+console programs that do a lot of different things concurrently, and want
+to serialize concurrent outputs sanely.
+
+It's increasingly easy to write concurrent programs, but all their status
+reporting has to feed back through the good old console, which is still
+obstinately serial.
+
+Haskell illustrates problem this well with this "Linus's first kernel"
+equivilant interleaving the output of 2 threads:
+
+	> import System.IO
+	> import Control.Concurrent.Async
+	> putStrLn (repeat 'A') `concurrently` putStrLn (repeat 'B')
+	BABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABA
+	BABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABA
+	...
+
+That's fun, but also horrible if you wanted to display some messages to
+the user:
+
+	> putStrLn "washed the car" `concurrently` putStrLn "walked the dog"
+	walwkaesdh etdh et hdeo gc
+	ar
+
+To add to the problem, we often want to run separate programs concurrently,
+which have output of their own to display. And, just to keep things
+interesting, sometimes a unix program will behave differently when stdout
+is not connected to a terminal (eg, `ls | cat`).
+
+To tame simple concurrent programs like these so they generate readable
+output involves a lot of plumbing. Something like, run the actions
+concurrently, taking care to capture the output of any commands, and then
+feed the output that the user should see though some sort of serializing
+channel to the display. Dealing with that when you just wanted a simple
+concurrent program risks ending up with a not-so-simple program.
+
+So, I wanted an library with basically 2 functions:
+
+[[!format haskell """
+	outputConcurrent :: String -> IO ()
+	createProcessConcurrent :: CreateProcess -> IO whatever
+"""]]
+
+The idea is, you make your program use `outputConcurrent` to display
+all its output, and each String you pass to that will be displayed serially,
+without getting mixed up with any other concurrent output.
+
+And, you make your program use `createProcessConcurrent` everywhere it
+starts a process that might output to stdout or stderr, and it'll likewise
+make sure its output is displayed serially.
+
+Oh, and `createProcessConcurrent` should avoid redirecting stdout and
+stderr away from the console, when no other concurrent output is happening.
+So, if programs are mostly run sequentially, they behave as they normally
+would at the console; any behavior changes should only occur when
+there is concurrency. (It might also be nice for it to allocate
+ttys and run programs there to avoid any behavior changes at all,
+although I have not tried to do that.)
+
+And that should be pretty much the whole API, although it's ok if it needs
+some function called by main to set it up:
+
+[[!format haskell """
+	import Control.Concurrent.Async
+	import Control.Concurrent.Output
+
+	main = withConcurrentOutput $
+		outputConcurrent "washed the car\n"
+			`concurrently`
+		createProcessConcurrent (proc "ls" [])
+			`concurrently`
+		outputConcurrent "walked the dog\n"
+"""]]
+
+	$ ./demo
+	washed the car
+	walked the dog
+	Maildir/  bin/  doc/  html/  lib/  mail/  mnt/  src/  tmp/
+
+I think that's a pretty good API to deal with this concurrent output
+problem. Anyone know of any other attempts at this I could learn from?
+
+I implemented this over the past 3 days and 320 lines of code.
+It got rather hairy:
+
+* It has to do buffering of the output.
+* There can be any quantity of output, but program memory use should be
+  reasonably small. Solved by buffering up to 1 mb of output in RAM, and
+  writing excess buffer to temp files.
+* Falling off the end of the program is complicated; there can be buffered
+  output to flush and it may have to wait for some processes to finish
+  running etc.
+* The locking was tough to get right! I could not have managed to
+  write it correctly without STM.
+
+It seems to work pretty great though. I got Propellor using it,
+and Propellor can now run actions concurrently!
+
+[[!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 b666810..08c9033 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 44 "watched it all, liked it" 8 "watched some, boring" 3 "too long for me" 15 "too haskell for me" 12 "not interested"]]
+[[!poll 45 "watched it all, liked it" 8 "watched some, boring" 3 "too long for me" 15 "too haskell for me" 12 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

Added a comment: Yes please
diff --git a/blog/entry/propelling_disk_images/comment_1_12fec96dedd83a8aa149224ed957f1c9._comment b/blog/entry/propelling_disk_images/comment_1_12fec96dedd83a8aa149224ed957f1c9._comment
new file mode 100644
index 0000000..8223226
--- /dev/null
+++ b/blog/entry/propelling_disk_images/comment_1_12fec96dedd83a8aa149224ed957f1c9._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="Cmt.minibill@fe3aa627d757be593269862d1d06b2cd5f1172f6"
+ nickname="Cmt.minibill"
+ subject="Yes please"
+ date="2015-10-23T22:11:13Z"
+ content="""
+Wrt using qemu: I really hope you actually implement it, it would be really nice for what I'm doing right now. 
+P.S.: you're awesome, your website usability from a mobile phone... Less so =)
+"""]]

tag
diff --git a/blog/entry/propelling_disk_images.mdwn b/blog/entry/propelling_disk_images.mdwn
index ee8d61e..5039f3f 100644
--- a/blog/entry/propelling_disk_images.mdwn
+++ b/blog/entry/propelling_disk_images.mdwn
@@ -115,3 +115,5 @@ write down the properties it has, and iteratively run Propellor against it
 until you think you have a full specification of it, and then
 use that to generate a new, clean disk image. Nice way to transition
 from sysadmin days of yore to a clean declaratively specified system.
+
+[[!tag propellor]]

oops
diff --git a/blog/entry/propelling_disk_images.mdwn b/blog/entry/propelling_disk_images.mdwn
index 1c28d0f..ee8d61e 100644
--- a/blog/entry/propelling_disk_images.mdwn
+++ b/blog/entry/propelling_disk_images.mdwn
@@ -83,7 +83,7 @@ board.
 Oh! I only just now realized that if you have a propellor host configured,
 like this example for my dialup gateway, `leech` --
 
-[[!language haskell """
+[[!format haskell """
 	leech = host "leech.kitenet.net"
 		& os (System (Debian (Stable "jessie")) "armel")
 		& Apt.installed ["linux-image-kirkwood", "ppp", "screen", "iftop"]
@@ -101,7 +101,7 @@ the same properties as the host!
 So, when my dialup gateway gets struck by lightning again, I could 
 use this to build a disk image for its replacement:
 
-[[!language haskell """
+[[!format haskell """
 	import qualified Propellor.Property.Hardware.SheevaPlug as SheevaPlug
 
 	laptop = host "darkstar.kitenet.net"

post
diff --git a/blog/entry/propelling_disk_images.mdwn b/blog/entry/propelling_disk_images.mdwn
new file mode 100644
index 0000000..1c28d0f
--- /dev/null
+++ b/blog/entry/propelling_disk_images.mdwn
@@ -0,0 +1,117 @@
+Following up on [[Then_and_Now]] ...
+
+In quiet moments at ICFP last August, I finished teaching
+[[code/Propellor]] to generate disk images. With an emphasis on doing a
+whole lot with very little new code and extreme amount of code reuse.
+
+For example, let's make a disk image with nethack on it. First, 
+we need to define a chroot. Disk image creation reuses propellor's chroot
+support, described back in [[propelling_containers]]. Any propellor
+properties can be assigned to the chroot, so it's easy to describe
+the system we want.
+
+[[!format haskell """
+	nethackChroot :: FilePath -> Chroot
+	nethackChroot d = Chroot.debootstrapped (System (Debian Stable) "amd64") mempty d
+		& Apt.installed ["linux-image-amd64"]
+		& Apt.installed ["nethack-console"]
+		& accountFor gamer
+		& gamer `hasInsecurePassword` "hello"
+		& gamer `hasLoginShell` "/usr/games/nethack"
+	  where gamer = User "gamer"
+"""]]
+
+Now to make an image from that chroot, we just have to tell
+propellor where to put the image file, some partitioning information,
+and to make it boot using grub.
+
+[[!format haskell """
+	nethackImage :: RevertableProperty
+	nethackImage = imageBuilt "/srv/images/nethack.img" nethackChroot
+		MSDOS (grubBooted PC)
+		[ partition EXT2 `mountedAt` "/boot"
+			`setFlag` BootFlag
+		, partition EXT4 `mountedAt` "/"
+			`addFreeSpace` MegaBytes 100
+		, swapPartition (MegaBytes 256)
+		]
+"""]]
+
+The disk image partitions default to being sized to fit exactly the files
+from the chroot that go into each partition, so, the disk image is as small
+as possible by default. There's a little DSL to configure the partitions.
+To give control over the partition size, it has some functions, like
+`addFreeSpace` and `setSize`. Other functions like `setFlag` and
+`extended` can further adjust the partitions. I think that worked out
+rather well; the partition specification is compact and avoids unecessary
+hardcoded sizes, while providing plenty of control.
+
+By the end of ICFP, I had Propellor building complete disk images,
+but no boot loader installed on them.
+
+----
+
+Fast forward to today. After stuggling with some strange grub behavior,
+I found a working method to install grub onto a disk image.
+
+The whole disk image feature weighs in at:
+
+203 lines to interface with parted  
+88 lines to format and mount partitions  
+90 lines for the partition table specification DSL and partition sizing  
+196 lines to generate disk images  
+75 lines to install grub on a disk image  
+652 lines of code total
+
+Which is about half the size of 
+[vmdebootstrap](http://packages.debian.org/vmdebootstrap)
+1/4th the size of [partman-base](http://packages.debian.org/partman-base)
+(probably 1/100th the size of total partman), and 1/13th the size of
+[live-build](http://packages.debian.org/live-build). All of which do
+similar things, in ways that seem to me to be much less flexible than
+Propellor.
+
+----
+
+One thing I'm considering doing is extending this so Propellor can
+use qemu-user-static to create disk images for eg, arm. Add some u-boot
+setup, and this could create bootable images for arm boards. A library of
+configs for various arm boards could then be included in Propellor.
+This would be a lot easier than running the Debian Installer on an arm
+board.
+
+Oh! I only just now realized that if you have a propellor host configured,
+like this example for my dialup gateway, `leech` --
+
+[[!language haskell """
+	leech = host "leech.kitenet.net"
+		& os (System (Debian (Stable "jessie")) "armel")
+		& Apt.installed ["linux-image-kirkwood", "ppp", "screen", "iftop"]
+		& privContent "/etc/ppp/peers/provider"
+		& privContent "/etc/ppp/pap-secrets"
+		& Ppp.onBoot
+		& hasPassword (User "root")
+		& Ssh.installed
+"""]]
+
+-- The host's properties can be extracted from it, using eg 
+`hostProperties leech` and reused to create a disk image with
+the same properties as the host!
+
+So, when my dialup gateway gets struck by lightning again, I could 
+use this to build a disk image for its replacement:
+
+[[!language haskell """
+	import qualified Propellor.Property.Hardware.SheevaPlug as SheevaPlug
+
+	laptop = host "darkstar.kitenet.net"
+		& SheevaPlug.diskImage "/srv/images/leech.img" (MegaBytes 2000)
+			(& propertyList "has all of leech's properties"
+				(hostProperties leech))
+"""]]
+
+This also means you can start with a manually built system,
+write down the properties it has, and iteratively run Propellor against it
+until you think you have a full specification of it, and then
+use that to generate a new, clean disk image. Nice way to transition
+from sysadmin days of yore to a clean declaratively specified system.

layout
diff --git a/blog/entry/propellor_orchestration.mdwn b/blog/entry/propellor_orchestration.mdwn
index 7d72447..594eac0 100644
--- a/blog/entry/propellor_orchestration.mdwn
+++ b/blog/entry/propellor_orchestration.mdwn
@@ -14,37 +14,37 @@ I like both of these ways to use propellor, but they only go so far...
 * Perhaps you have a lot of hosts, and would like to run propellor on them
   all concurrently.
 
-	master = host "master.example.com"
-		& concurrently conducts alotofhosts
+		master = host "master.example.com"
+			& concurrently conducts alotofhosts
 
 * Perhaps you want to run propellor on your dns server last,
   so when you add a new webserver host, it gets set up and working
   before the dns is updated to point to it.
 
-	master = host "master.example.com"
-		& conducts webservers
-			`before` conducts dnsserver
+		master = host "master.example.com"
+			& conducts webservers
+				`before` conducts dnsserver
 
 * Perhaps you have something more complex, with multiple 
   subnets that propellor can run in concurrently, finishing up by
   updating that dnsserver.
 
-	master = host "master.example.com"
-		& concurrently conducts [sub1, sub2]
-			`before` conducts dnsserver
+		master = host "master.example.com"
+			& concurrently conducts [sub1, sub2]
+				`before` conducts dnsserver
 	
-	sub1 = "master.subnet1.example.com"
-		& concurrently conducts webservers
-		& conducts loadbalancers
+		sub1 = "master.subnet1.example.com"
+			& concurrently conducts webservers
+			& conducts loadbalancers
 	
-	sub2 = "master.subnet2.example.com"
-		& conducts dockerservers
+		sub2 = "master.subnet2.example.com"
+			& conducts dockerservers
 
 * Perhaps you need to first run some command that creates a VPS host, and
   then want to run propellor on that host to set it up.
 
-	vpscreate h = cmdProperty "vpscreate" [hostName h]
-		`before` conducts h
+		vpscreate h = cmdProperty "vpscreate" [hostName h]
+			`before` conducts h
 
 All those scenarios are supported by propellor now!
 

blog update
diff --git a/blog/entry/propellor_orchestration.mdwn b/blog/entry/propellor_orchestration.mdwn
new file mode 100644
index 0000000..7d72447
--- /dev/null
+++ b/blog/entry/propellor_orchestration.mdwn
@@ -0,0 +1,87 @@
+[[!tag propellor]]
+
+With the disclamer that I don't really know much about
+<a href="https://en.wikipedia.org/wiki/Orchestration_(computing)">orchestration</a>,
+I have added support for something resembling it to [[code/Propellor]].
+
+Until now, when using propellor to manage a bunch of hosts, you
+updated them one at a time by running `propellor --spin $somehost`,
+or maybe you set up a central git repository, and a cron job to run
+propellor on each host, pulling changes from git.
+
+I like both of these ways to use propellor, but they only go so far...
+
+* Perhaps you have a lot of hosts, and would like to run propellor on them
+  all concurrently.
+
+	master = host "master.example.com"
+		& concurrently conducts alotofhosts
+
+* Perhaps you want to run propellor on your dns server last,
+  so when you add a new webserver host, it gets set up and working
+  before the dns is updated to point to it.
+
+	master = host "master.example.com"
+		& conducts webservers
+			`before` conducts dnsserver
+
+* Perhaps you have something more complex, with multiple 
+  subnets that propellor can run in concurrently, finishing up by
+  updating that dnsserver.
+
+	master = host "master.example.com"
+		& concurrently conducts [sub1, sub2]
+			`before` conducts dnsserver
+	
+	sub1 = "master.subnet1.example.com"
+		& concurrently conducts webservers
+		& conducts loadbalancers
+	
+	sub2 = "master.subnet2.example.com"
+		& conducts dockerservers
+
+* Perhaps you need to first run some command that creates a VPS host, and
+  then want to run propellor on that host to set it up.
+
+	vpscreate h = cmdProperty "vpscreate" [hostName h]
+		`before` conducts h
+
+All those scenarios are supported by propellor now!
+
+Well, I 
+<a href="http://propellor.branchable.com/todo/concurrency/">haven't actually implemented <tt>concurrently</tt> yet</a>,
+but the point is that the `conducts` property can be used with any
+of propellor's property combinators, like `before` etc,
+to express all kinds of scenarios.
+
+The `conducts` property works in combination with an `orchestrate` function
+to set up all the necessary stuff to let one host ssh into another and run
+propellor there.
+
+	main = defaultMain (orchestrate hosts)
+
+	hosts = 
+		[ master
+		, webservers 
+		, ...
+		]
+
+The `orchestrate` function does a bunch of stuff:
+
+* Builds up a graph of what conducts what.
+* Removes any cycles that might have snuck in by accident, before they
+  cause foot shooting.
+* Arranges for the ssh keys to be accepted as necessary.  
+  Note that you you need to add ssh key properties to all relevant hosts
+  so it knows what keys to trust.
+* Arranges for the private data of a host to be provided to
+  the hosts that conduct it, so they can pass it along.
+
+I've very pleased that I was able to add the Propellor.Property.Conductor
+module implementing this with only a tiny change to the rest of propellor.
+Almost everything needed to implement it was there in propellor's
+infrastructure already. 
+
+Also kind of cool that it only needed 13 lines of imperative code, the
+other several hundred lines of the
+[implementation](http://hackage.haskell.org/package/propellor-2.11.0/docs/src/Propellor-Property-Conductor.html) being all pure code.

tag
diff --git a/blog/entry/birdplanesupermonoid.mdwn b/blog/entry/birdplanesupermonoid.mdwn
index f681023..76fe1f1 100644
--- a/blog/entry/birdplanesupermonoid.mdwn
+++ b/blog/entry/birdplanesupermonoid.mdwn
@@ -1,5 +1,5 @@
 [[!meta title="it's a bird, it's a plane, it's a super monoid for propellor"]]
-[[!tag propellor]]
+[[!tag propellor haskell]]
 
 I've been doing a little bit of dynamically typed programming in Haskell,
 to improve [[code/Propellor]]'s `Info` type. The result is kind of

comment
diff --git a/blog/entry/birdplanesupermonoid/comment_6_e7e4c27d99d701a32fc4d1ed5f8daba0._comment b/blog/entry/birdplanesupermonoid/comment_6_e7e4c27d99d701a32fc4d1ed5f8daba0._comment
new file mode 100644
index 0000000..ca1457a
--- /dev/null
+++ b/blog/entry/birdplanesupermonoid/comment_6_e7e4c27d99d701a32fc4d1ed5f8daba0._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 6"""
+ date="2015-10-19T15:54:59Z"
+ content="""
+Hmm, took me a while to see how to implement getInfo, since that
+needs `extract :: InfoEntry -> Maybe a`. But indeed, it can be done,
+since `a` is Typeable:
+
+	extract (InfoEntry a) = fromDynamic (toDyn a)
+
+This indeed simplified the code, thanks!
+"""]]

Added a comment
diff --git a/blog/entry/birdplanesupermonoid/comment_5_50f0b51635b84b27902ac69b8b765644._comment b/blog/entry/birdplanesupermonoid/comment_5_50f0b51635b84b27902ac69b8b765644._comment
new file mode 100644
index 0000000..07b4502
--- /dev/null
+++ b/blog/entry/birdplanesupermonoid/comment_5_50f0b51635b84b27902ac69b8b765644._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="comment 5"
+ date="2015-10-19T10:42:10Z"
+ content="""
+I would suggest something this:
+
+    newtype Info = Info [InfoEntry]
+        deriving (Monoid)
+
+    data InfoEntry where
+      Info :: (IsInfo a, Typeable a) => a -> InfoEntry
+
+
+this way, you will store the `IsInfo` class together with the entry. Then you can add a method
+
+        describeInfoEntry :: a -> String
+
+to the `IsInfo` class, and with this you can implement a function
+``` 
+describe :: Info -> String
+```
+that gives a nice, info-specific overview of all the info that works for all entries, without the need to know what kind of Info types are there.
+
+Similarly, this way you can filter on `propigateInfo` generically.
+
+
+
+"""]]

comment
diff --git a/blog/entry/dealing_with_dialup/comment_4_6af32f5d4c871e8745a11f03724288d9._comment b/blog/entry/dealing_with_dialup/comment_4_6af32f5d4c871e8745a11f03724288d9._comment
new file mode 100644
index 0000000..3cac6d7
--- /dev/null
+++ b/blog/entry/dealing_with_dialup/comment_4_6af32f5d4c871e8745a11f03724288d9._comment
@@ -0,0 +1,34 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 4"""
+ date="2015-10-18T18:36:06Z"
+ content="""
+I don't know about line quality. Mine seems somewhat scratchy, and I
+probably don't get the fastest 56k V.whatever connection that I enjoyed in
+dialup's heydey, but back then I was dialing up from a non-rural location.
+So, apples and oranges.
+
+And then, the quality of dialup ISP's is surely much lower now too. Mine
+can't debug a simple routing problem that's clearly present in their
+internal network. I only recently learned just how much ISP's have
+consolidated. While my area still seems to have 2 or 3 functional ISPs,
+they all turn out to be Virtual ISP's that are leasing everything from
+the same VISP provider. So, the ISP you call to get tech support probably
+does not have anything to do with the actual modem and network operator.
+
+Protocols like ssh still work just fine, and there are nice options now
+like mosh as well. git makes it easy to work locally. On the other hand,
+the web fares increasingly poorly on dialup. Pages full of dozens of web
+bugs and ads, web fonts that break progressive page load, massive balls of
+compiled javascript, etc. Best to turn off and block as much of that as you
+can; luckily everyone is getting increasingly fed up with that crap and
+perhaps it will eventually be ad blocked into oblivion?
+
+Even then, the web is increasingly not tuned for dialup. You web browser
+may try to open a large number of concurrent connections when loading a
+page, and so swamp them all to the point nothing loads. Web servers often
+time out a client that is receiving data at a dialup level crawl. It may be
+that a remote proxy that strips the crap and avoids the timeout issue
+becomes increasingly necessary (much as they were, at least for a while,
+for mobile phone web browsing).
+"""]]

Added a comment: The future of dialup
diff --git a/blog/entry/dealing_with_dialup/comment_3_746e0fbf95353bdcf050f42bb19ef69b._comment b/blog/entry/dealing_with_dialup/comment_3_746e0fbf95353bdcf050f42bb19ef69b._comment
new file mode 100644
index 0000000..ffbccd2
--- /dev/null
+++ b/blog/entry/dealing_with_dialup/comment_3_746e0fbf95353bdcf050f42bb19ef69b._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="yrogerg64"
+ subject="The future of dialup"
+ date="2015-10-18T05:40:39Z"
+ content="""
+Great post and I have implemented much of what you have suggested although as a mere mortal, I have to keep things fairly simple. :-P  I live in rural northern California and lately I am somewhat concerned about the future of dialup as I have no cell signal where I am at.  Although I do have satellite broadband (aka fraudband) generously provided by a family member, the latency is painful.  I prefer to work from dialup (the cli most of the time...it's easier on my aging eyes) as I tend to work more efficiently.  The news is replete with stories of unmaintained landline networks in rural America with the subsequent diminished call clarity.  What is your experience over on your side?   
+"""]]

Added a comment: Naming Brainstorm
diff --git a/blog/entry/birdplanesupermonoid/comment_4_f17069dae665253b77b2337c09c45ec5._comment b/blog/entry/birdplanesupermonoid/comment_4_f17069dae665253b77b2337c09c45ec5._comment
new file mode 100644
index 0000000..ee1cc3a
--- /dev/null
+++ b/blog/entry/birdplanesupermonoid/comment_4_f17069dae665253b77b2337c09c45ec5._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="a@92214b2eae95307f511e06845d2cb5b5931b00a3"
+ nickname="a"
+ subject="Naming Brainstorm"
+ date="2015-10-18T05:35:43Z"
+ content="""
+> And finally, I keep trying to think of a better name than \"Info\".
+
+Abstract stuff like this is always hard and unsatisfactory. Here's some ideas, though:
+
+- Tag, field, card, note, sticker, stamp
+- Entry, manifest, inventory, catalog
+- Context
+- Fact, term
+"""]]

Added a comment
diff --git a/blog/entry/birdplanesupermonoid/comment_3_032545f55f8d8126db72351d2db8e150._comment b/blog/entry/birdplanesupermonoid/comment_3_032545f55f8d8126db72351d2db8e150._comment
new file mode 100644
index 0000000..628ccc5
--- /dev/null
+++ b/blog/entry/birdplanesupermonoid/comment_3_032545f55f8d8126db72351d2db8e150._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="josh@ccccabe84317e1b7429fd465de0b38fd54925dea"
+ nickname="josh"
+ subject="comment 3"
+ date="2015-10-18T05:23:52Z"
+ content="""
+You could declare that to hold any instance of the appropriate typeclass.
+"""]]

comment
diff --git a/blog/entry/birdplanesupermonoid/comment_2_28ba57683bfcf34b43401ef049f1bcfe._comment b/blog/entry/birdplanesupermonoid/comment_2_28ba57683bfcf34b43401ef049f1bcfe._comment
new file mode 100644
index 0000000..a410b15
--- /dev/null
+++ b/blog/entry/birdplanesupermonoid/comment_2_28ba57683bfcf34b43401ef049f1bcfe._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2015-10-18T03:03:17Z"
+ content="""
+Been a while since I watched a talk on vinyl or similar, but IIRC
+records containing different fields would have different types.
+Since propellor uses `data Host = Host HostName [Property] Info`,
+and  operates on lists `[Host]`, making the Info type vary depending
+on what's in it would present difficulties.
+"""]]

Added a comment: Extensible record types?
diff --git a/blog/entry/birdplanesupermonoid/comment_1_d930346322bceacc51bb7d690d494158._comment b/blog/entry/birdplanesupermonoid/comment_1_d930346322bceacc51bb7d690d494158._comment
new file mode 100644
index 0000000..4a90d95
--- /dev/null
+++ b/blog/entry/birdplanesupermonoid/comment_1_d930346322bceacc51bb7d690d494158._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="josh@ccccabe84317e1b7429fd465de0b38fd54925dea"
+ nickname="josh"
+ subject="Extensible record types?"
+ date="2015-10-17T22:32:41Z"
+ content="""
+Have you considered using an extensible record type?  The current generation of extensible record types uses type-level strings as field names, and arbitrary types as values.  That also allows you a form of \"static duck typing\": for instance, you can write a function that accepts only an Info type that has a record with a field \"hostname\" of type String.
+"""]]

tag
diff --git a/blog/entry/then_and_now.mdwn b/blog/entry/then_and_now.mdwn
index b86eafc..597b7e7 100644
--- a/blog/entry/then_and_now.mdwn
+++ b/blog/entry/then_and_now.mdwn
@@ -61,3 +61,5 @@ plan here to replace Debian Installer (although with a few hundred more lines
 of code, [[propellor_is_d-i_2.0]]); indeed I'm just adding generic useful stuff
 and building further stuff out of it without any particular end goal. Perhaps
 that's the real difference.
+
+[[!tag propellor]]

simplify
diff --git a/blog/entry/birdplanesupermonoid.mdwn b/blog/entry/birdplanesupermonoid.mdwn
index a212355..f681023 100644
--- a/blog/entry/birdplanesupermonoid.mdwn
+++ b/blog/entry/birdplanesupermonoid.mdwn
@@ -122,7 +122,7 @@ this:
 
 [[!format haskell """
 	instance Show Info where
-	        show (Info l) = "Info " ++ show (map (dynTypeRep . fst) l)
+	        show (Info l) = "Info " ++ show (map dynTypeRep l)
 """]]
 
 The resulting long list of the types of vales stored in a host's info is not

fix format
diff --git a/blog/entry/birdplanesupermonoid.mdwn b/blog/entry/birdplanesupermonoid.mdwn
index 188814b..a212355 100644
--- a/blog/entry/birdplanesupermonoid.mdwn
+++ b/blog/entry/birdplanesupermonoid.mdwn
@@ -25,7 +25,7 @@ The key to doing it is `Data.Dynamic`. Thanks to Joachim Breitner for
 suggesting I could use it here. What I arrived at is this type (slightly
 simplified):
 
-[[!language haskell """
+[[!format haskell """
 newtype Info = Info [Dynamic]
 	deriving (Monoid)
 """]]
@@ -37,7 +37,7 @@ So far, this is utterly scary to me. To tame it, the Info constructor is not
 exported, and so the only way to create an Info is to start with `mempty`
 and use this function:
 
-[[!language haskell """
+[[!format haskell """
 addInfo :: (IsInfo v, Monoid v) => Info -> v -> Info
 addInfo (Info l) v = Info (toDyn v : l)
 """]]
@@ -51,7 +51,7 @@ mess.
 
 Anything you can add into an Info, you can get back out:
 
-[[!language haskell """
+[[!format haskell """
 getInfo :: (IsInfo v, Monoid v) => Info -> v
 getInfo (Info l) = mconcat (mapMaybe fromDynamic (reverse l))
 """]]
@@ -80,7 +80,7 @@ a loop of foo running Propellor on bar, running Propellor on foo, ...
 To detect such loops, each Host's Info should contain a list of the
 Hosts it's controlling. Which is not hard to accomplish:
 
-[[!language haskell """
+[[!format haskell """
 newtype Controlling = Controlled [Host]
 	deriving (Typeable, Monoid)
 
@@ -120,7 +120,7 @@ So, that's a useful technique. I do wonder if I could somehow make
 as it is the list can get long. And, to show Info, the best I could do was
 this:
 
-[[!language haskell """
+[[!format haskell """
 	instance Show Info where
 	        show (Info l) = "Info " ++ show (map (dynTypeRep . fst) l)
 """]]

blog update
diff --git a/blog/entry/birdplanesupermonoid.mdwn b/blog/entry/birdplanesupermonoid.mdwn
new file mode 100644
index 0000000..188814b
--- /dev/null
+++ b/blog/entry/birdplanesupermonoid.mdwn
@@ -0,0 +1,137 @@
+[[!meta title="it's a bird, it's a plane, it's a super monoid for propellor"]]
+[[!tag propellor]]
+
+I've been doing a little bit of dynamically typed programming in Haskell,
+to improve [[code/Propellor]]'s `Info` type. The result is kind of
+interesting in a scary way.
+
+`Info` started out as a big record type, containing all the different sorts
+of metadata that Propellor needed to keep track of. Host IP addresses, DNS
+entries, ssh public keys, docker image configuration parameters... This got
+quite out of hand. `Info` needed to have its hands in everything,
+even types that should have been private to their module.
+
+To fix that, recent versions of [[code/Propellor]] let a single
+`Info` contain many different types of values. Look at it one way and
+it contains DNS entries; look at it another way and it contains ssh public
+keys, etc. 
+
+As an émigré from lands where you can never know what type of value is in
+a `$foo` until you look, this was a scary prospect at first, but I found
+it's possible to have the benefits of dynamic types and the safety of
+static types too.
+
+The key to doing it is `Data.Dynamic`. Thanks to Joachim Breitner for
+suggesting I could use it here. What I arrived at is this type (slightly
+simplified):
+
+[[!language haskell """
+newtype Info = Info [Dynamic]
+	deriving (Monoid)
+"""]]
+
+So Info is a monoid, and it holds of a bunch of dynamic values, which could
+each be of any type at all. Eep!
+
+So far, this is utterly scary to me. To tame it, the Info constructor is not
+exported, and so the only way to create an Info is to start with `mempty`
+and use this function:
+
+[[!language haskell """
+addInfo :: (IsInfo v, Monoid v) => Info -> v -> Info
+addInfo (Info l) v = Info (toDyn v : l)
+"""]]
+
+The important part of that is that only allows adding values that are in
+the `IsInfo` type class. That prevents the foot shooting associated with
+dynamic types, by only allowing use of types that make sense as Info.
+Otherwise arbitrary Strings etc could be passed to addInfo by accident, and
+all get concated together, and that would be a total dynamic programming
+mess.
+
+Anything you can add into an Info, you can get back out:
+
+[[!language haskell """
+getInfo :: (IsInfo v, Monoid v) => Info -> v
+getInfo (Info l) = mconcat (mapMaybe fromDynamic (reverse l))
+"""]]
+
+Only monoids can be stored in Info, so if you ask for a type that an Info
+doesn't contain, you'll get back `mempty`.
+
+Crucially, `IsInfo` is an open type class. Any module in Propellor
+can make a new data type and make it an instance of `IsInfo`, and then that
+new data type can be stored in the `Info` of a `Property`, and any `Host` that
+uses the `Property` will have that added to its `Info`, available for later
+introspection.
+
+----
+
+For example, this weekend I'm extending Propellor to have controllers: 
+Hosts that are responsible for running Propellor on some other hosts.
+Useful if you want to run `propellor` once and have it update the
+configuration of an entire network of hosts.
+
+There can be whole chains of controllers controlling other controllers etc.
+The problem is, what if host `foo` has the property `controllerFor bar`
+and host `bar` has the property `controllerFor foo`? I want to avoid
+a loop of foo running Propellor on bar, running Propellor on foo, ...
+
+To detect such loops, each Host's Info should contain a list of the
+Hosts it's controlling. Which is not hard to accomplish:
+
+[[!language haskell """
+newtype Controlling = Controlled [Host]
+	deriving (Typeable, Monoid)
+
+isControlledBy :: Host -> Controlling -> Bool
+h `isControlledBy` (Controlled hs) = any (== hostName h) (map hostName hs)
+
+instance IsInfo Controlling where
+	propigateInfo _ = True
+
+mkControllingInfo :: Host -> Info
+mkControllingInfo controlled = addInfo mempty (Controlled [controlled])
+
+getControlledBy :: Host -> Controlling
+getControlledBy = getInfo . hostInfo
+
+isControllerLoop :: Host -> Host -> Bool
+isControllerLoop controller controlled = go S.empty controlled
+  where
+	go checked h
+		| controller `isControlledBy` c = True
+		-- avoid checking loops that have been checked before
+		| hostName h `S.member` checked = False
+		| otherwise = any (go (S.insert (hostName h) checked)) l
+	  where
+		c@(Controlled l) = getControlledBy h
+"""]]
+
+This is all internal to the module that needs it; the rest of
+propellor doesn't need to know that the Info is using used for this.
+And yet, the necessary information about Hosts is gathered as
+propellor runs.
+
+----
+
+So, that's a useful technique. I do wonder if I could somehow make
+`addInfo` combine together values in the list that have the same type;
+as it is the list can get long. And, to show Info, the best I could do was
+this:
+
+[[!language haskell """
+	instance Show Info where
+	        show (Info l) = "Info " ++ show (map (dynTypeRep . fst) l)
+"""]]
+
+The resulting long list of the types of vales stored in a host's info is not
+a useful as it could be. Of course, `getInfo` can be used to get any
+particular type of value:
+
+	*Main> hostInfo kite
+	Info [InfoVal System,PrivInfo,PrivInfo,Controlling,DnsInfo,DnsInfo,DnsInfo,AliasesInfo, ...
+	*Main> getInfo (hostInfo kite) :: AliasesInfo
+ 	AliasesInfo (fromList ["downloads.kitenet.net","git.joeyh.name","imap.kitenet.net","nntp.olduse.net" ...
+
+And finally, I keep trying to think of a better name than "Info".
diff --git a/blog/propellor.mdwn b/blog/propellor.mdwn
index a719ba4..b837463 100644
--- a/blog/propellor.mdwn
+++ b/blog/propellor.mdwn
@@ -1 +1 @@
-[[!inline pages="blog/entry/* and link(propellor) and !*/Discussion" actions=yes show="10"]]
+[[!inline pages="blog/entry/* and link(propellor) and !*/Discussion" actions=yes show="100"]]

Added a comment: Regarding "propellor spin" commits
diff --git a/blog/entry/our_beautiful_fake_histories/comment_4_918e8268dde02ccdc74de1af905945c7._comment b/blog/entry/our_beautiful_fake_histories/comment_4_918e8268dde02ccdc74de1af905945c7._comment
new file mode 100644
index 0000000..a47213f
--- /dev/null
+++ b/blog/entry/our_beautiful_fake_histories/comment_4_918e8268dde02ccdc74de1af905945c7._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ subject="Regarding &quot;propellor spin&quot; commits"
+ date="2015-09-30T21:06:30Z"
+ content="""
+While I agree with the general sentiment of this blog post (GitHub's homepage now advertises that its git GUI allows you to \"craft the perfect commit\"), I don't like propellor's automatically committing to git every time it is run.  The problem there is that it doesn't give the user an opportunity to write a commit message, which makes it much more fiddly to perform reversions.  If I can look at my branch history and know what each (recent) commit does just by looking at the commit message, it's easy to see what I need to revert to undo something that I've decided was a bad idea.  If changes are hidden in \"propellor spin\" commits, I end up having to check the diffs of each of those commits to be sure I've reverted everything I wanted to revert.
+
+I've worked around this by wrapping `propellor --spin` in a simple shell script that bails if I've any uncommitted changes, so I can ignore all \"propellor spin\" commits since all they do is make sure the head of the branch is PGP-signed.
+"""]]

Environment variable TS_FORMAT.
diff --git a/code/moreutils/discussion.mdwn b/code/moreutils/discussion.mdwn
index a9a06f9..22f7279 100644
--- a/code/moreutils/discussion.mdwn
+++ b/code/moreutils/discussion.mdwn
@@ -473,3 +473,5 @@ It would be nice to have an option to add a blank line or other string as an ind
 would break into a different cluster whenever the time from one line to the next exceeds 0.1 second, and there could be another option to set the break string to something other than "\n", which is the default.
 
 It would be nice to show both stdin and stderr, and distinguish them.  (Otherwise one needs 2>&1 to combine stdin and stderr.)  But that could alternatively be done with a colorizer, which would be a good separate tool to have.
+
+I'd like to have environment variable TS_FORMAT to avoid typing custom format every time I use ts. Default is very inconvenient to read for non-native english speaker; I personally almost always use '%H:%M:%S'.

Added a comment: Thanks
diff --git a/blog/entry/then_and_now/comment_2_aaa9abbe0968ff2ca7a0b00c9a4d2584._comment b/blog/entry/then_and_now/comment_2_aaa9abbe0968ff2ca7a0b00c9a4d2584._comment
new file mode 100644
index 0000000..e22e9c6
--- /dev/null
+++ b/blog/entry/then_and_now/comment_2_aaa9abbe0968ff2ca7a0b00c9a4d2584._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="sre@f4ca29a0dbc05f828c94a1906e7e45d0b67b2ef6"
+ nickname="sre"
+ subject="Thanks"
+ date="2015-09-10T21:32:04Z"
+ content="""
+Thanks for your work on partitioning in d-i and greetings from Oldenburg :)
+
+-- Sebastian
+"""]]

Added a comment: propellor lifts you up where you belong
diff --git a/blog/entry/then_and_now/comment_1_7472a4e09be5ab8d8088fd6a792f73d8._comment b/blog/entry/then_and_now/comment_1_7472a4e09be5ab8d8088fd6a792f73d8._comment
new file mode 100644
index 0000000..f3d3553
--- /dev/null
+++ b/blog/entry/then_and_now/comment_1_7472a4e09be5ab8d8088fd6a792f73d8._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="https://woid.cryptobitch.de/foobar"
+ subject="propellor lifts you up where you belong"
+ date="2015-08-27T17:57:46Z"
+ content="""
+Thanks joey for just building good software. I'd appreciate to have a new d-i sometime in the future.
+"""]]

update
diff --git a/blog/entry/then_and_now.mdwn b/blog/entry/then_and_now.mdwn
index 5c988fa..b86eafc 100644
--- a/blog/entry/then_and_now.mdwn
+++ b/blog/entry/then_and_now.mdwn
@@ -5,7 +5,7 @@ piece of work, a mass of semi-object-oriented, super extensible shell code that
 sprang fully formed from the brow of Anton. And in many ways, it's mad, full of
 sector alignment twiddling math implemented in tens of thousands of lines of
 shell script scattered amoung hundreds of tiny files that are impossible to keep
-straight. In the tiny Oldenburg Developers meeting, full of obscure hardware
+straight. In the tiny Oldenburg Developers Meeting, full of obscure hardware
 and crazy intensity of ideas like porting Debian to VAXen, we hack late into
 the night, night after night, and crash on the floor.
 

update
diff --git a/blog/entry/then_and_now.mdwn b/blog/entry/then_and_now.mdwn
index b978d79..5c988fa 100644
--- a/blog/entry/then_and_now.mdwn
+++ b/blog/entry/then_and_now.mdwn
@@ -4,7 +4,7 @@ somewhat reluctantly decided to use it. Partman is in some ways a beautful
 piece of work, a mass of semi-object-oriented, super extensible shell code that
 sprang fully formed from the brow of Anton. And in many ways, it's mad, full of
 sector alignment twiddling math implemented in tens of thousands of lines of
-shell script scatted amoung hundreds of tiny files that are impossible to keep
+shell script scattered amoung hundreds of tiny files that are impossible to keep
 straight. In the tiny Oldenburg Developers meeting, full of obscure hardware
 and crazy intensity of ideas like porting Debian to VAXen, we hack late into
 the night, night after night, and crash on the floor.

blog update
diff --git a/blog/entry/then_and_now.mdwn b/blog/entry/then_and_now.mdwn
new file mode 100644
index 0000000..b978d79
--- /dev/null
+++ b/blog/entry/then_and_now.mdwn
@@ -0,0 +1,63 @@
+It's 2004 and I'm in Oldenburg DE, working on the Debian Installer. Colin and I
+pair program on partman, its new partitioner, to get it into shape. We've
+somewhat reluctantly decided to use it. Partman is in some ways a beautful
+piece of work, a mass of semi-object-oriented, super extensible shell code that
+sprang fully formed from the brow of Anton. And in many ways, it's mad, full of
+sector alignment twiddling math implemented in tens of thousands of lines of
+shell script scatted amoung hundreds of tiny files that are impossible to keep
+straight. In the tiny Oldenburg Developers meeting, full of obscure hardware
+and crazy intensity of ideas like porting Debian to VAXen, we hack late into
+the night, night after night, and crash on the floor.
+
+[[!img pics/oldenburg/8/dscf0035.jpg size=640x alt="sepia toned hackers round a table"]]
+
+It's 2015 and I'm at a Chinese bakery, then at the Berkeley pier, then in a SF
+food truck lot, catching half an hour here and there in my vacation to add some
+features to [[code/Propellor]]. Mostly writing down data types for things like
+filesystem formats, partition layouts, and then some small amount of haskell
+code to use them in generic ways. Putting these peices together and reusing
+stuff already in Propellor (like [[chroot creation|propelling_containers]]).
+
+Before long I have this, which is only 2 undefined functions away from
+(probably) working:
+
+[[!format haskell """
+let chroot d = Chroot.debootstrapped (System (Debian Unstable) "amd64") mempty d
+ 		& Apt.installed ["openssh-server"]
+		& ...
+    partitions = fitChrootSize MSDOS
+		[ (Just "/boot", mkPartiton EXT2)
+		, (Just "/", mkPartition EXT4)
+		, (Nothing, const (mkPartition LinuxSwap (MegaBytes 256)))
+		]
+ in Diskimage.built chroot partitions (grubBooted PC)
+"""]]
+
+This is at least a replication of vmdebootstrap, generating a bootable disk
+image from that config and 400 lines of code, with enormous customizability
+of the disk image contents, using all the abilities of Propellor. But is also,
+effectively, a replication of everything partman is used for (aside from UI and
+RAID/LVM).
+
+[[!img blog/pics/sfbay.png alt="sailboat on the SF bay"]]
+
+What a difference a decade and better choices of architecture make! In many
+ways, this is the loosely coupled, extensible, highly configurable system
+partman aspired to be. Plus elegance. And I'm writing it on a lark, because I
+have some spare half hours in my vacation.
+
+Past Debian Installer team lead Tollef stops by for lunch, I show him
+the code, and we have the conversation old d-i developers always have about
+partman.
+
+I can't say that partman was a failure, because it's been used by millions to
+install Debian and Ubuntu and etc for a decade. Anything that deletes that many
+Windows partitions is a success. But it's been an unhappy success. Nobody has
+ever had a good time writing partman recipes; the code has grown duplication
+and unmaintainability. 
+
+I can't say that these extensions to Propellor will be a success; there's no
+plan here to replace Debian Installer (although with a few hundred more lines
+of code, [[propellor_is_d-i_2.0]]); indeed I'm just adding generic useful stuff
+and building further stuff out of it without any particular end goal. Perhaps
+that's the real difference.
diff --git a/blog/pics/sfbay.png b/blog/pics/sfbay.png
new file mode 100644
index 0000000..a0d9a5a
Binary files /dev/null and b/blog/pics/sfbay.png differ

removed
diff --git a/blog/entry/propellor_is_d-i_2.0/comment_4_039c3a5147cf32bf8b1af523da5bb757._comment b/blog/entry/propellor_is_d-i_2.0/comment_4_039c3a5147cf32bf8b1af523da5bb757._comment
deleted file mode 100644
index c47522e..0000000
--- a/blog/entry/propellor_is_d-i_2.0/comment_4_039c3a5147cf32bf8b1af523da5bb757._comment
+++ /dev/null
@@ -1,8 +0,0 @@
-[[!comment format=mdwn
- username="wires"
- ip="82.161.183.192"
- subject="nice"
- date="2014-09-27T10:01:13Z"
- content="""
-Nice and simple solution again! would love to see this developed further. Also wondering if it is useful to combine this with (parts of) [nix](https://nixos.org/nix/)... 
-"""]]

add poptail and peeif
diff --git a/code/moreutils/discussion.mdwn b/code/moreutils/discussion.mdwn
index 8536306..a9a06f9 100644
--- a/code/moreutils/discussion.mdwn
+++ b/code/moreutils/discussion.mdwn
@@ -1,6 +1,19 @@
 Feel free to edit this page to suggest tools to add, or make any other
 comments --[[Joey]]
 
+## poptail and peeif
+
+I just finished two utilities that might be general purpose enough for the collection.  They're on github here:
+<https://github.com/ohspite/evenmoreutils>
+
+Here's the summary:
+
+peeif - Pipe STDIN to any number of commands, but only if the exit status of the previous command was zero. Behavior can also be inverted to "peeuntil".
+
+poptail - Print and remove the last lines (or bytes) from a file. This is done without reading the whole file and without copying. Can be used with parallel to batch process the lines of a file.
+
+--Don (PS-thanks for your work on moreutils and your other projects)
+
 ## more exposure for errno
 
 After having moreutils installed for a couple months I just stumbled upon `errno` which I find incredibly useful!

Added a comment: Overcoming barriers to entry
diff --git a/blog/entry/our_beautiful_fake_histories/comment_3_82dfe809cdbf05e01ef6dacd51350bbf._comment b/blog/entry/our_beautiful_fake_histories/comment_3_82dfe809cdbf05e01ef6dacd51350bbf._comment
new file mode 100644
index 0000000..d6088ec
--- /dev/null
+++ b/blog/entry/our_beautiful_fake_histories/comment_3_82dfe809cdbf05e01ef6dacd51350bbf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="lynoure@986e008d5d5f5b506ab03d704897da447556f2e6"
+ nickname="lynoure"
+ subject="Overcoming barriers to entry"
+ date="2015-08-16T16:04:56Z"
+ content="""
+Both of the alternatives (the real messy history and the beautiful fake history) have their own barriers to entry to committing. 
+The real messy history is of course sometimes a bit harder to follow, but on the other hand it shows that software is not written by people who just wake up one morning, sit down and write perfect bugless code in one sitting. 
+It's easier to feel one is 'good enough' to contribute when the contribution is going into a project that clearly has allowed others to learn from mistakes before.
+"""]]

add news item for github-backup 1.20150807
diff --git a/code/github-backup/news/version_1.20141110.mdwn b/code/github-backup/news/version_1.20141110.mdwn
deleted file mode 100644
index 2c24e28..0000000
--- a/code/github-backup/news/version_1.20141110.mdwn
+++ /dev/null
@@ -1,4 +0,0 @@
-github-backup 1.20141110 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Orphaned the Debian package.
-     (I continue to maintain github-backup upstream.)"""]]
\ No newline at end of file
diff --git a/code/github-backup/news/version_1.20150807.mdwn b/code/github-backup/news/version_1.20150807.mdwn
new file mode 100644
index 0000000..13d0ccd
--- /dev/null
+++ b/code/github-backup/news/version_1.20150807.mdwn
@@ -0,0 +1,8 @@
+github-backup 1.20150807 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Added bash completion.
+   * Add --no-forks flag that turns off backing up forks.
+     Thanks, Phil Ruffwind.
+   * Avoid nonzero exit due to temporary failures that can be retried next
+     time github-backup runs, so that it can be used in a cron job with eg,
+     chronic."""]]
\ No newline at end of file

add news item for filters 2.54
diff --git a/code/filters/news/version_2.48.mdwn b/code/filters/news/version_2.48.mdwn
deleted file mode 100644
index 782ff86..0000000
--- a/code/filters/news/version_2.48.mdwn
+++ /dev/null
@@ -1,4 +0,0 @@
-filters 2.48 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Mention that some filters support reading from input files.
-     Closes: #[569764](http://bugs.debian.org/569764)"""]]
\ No newline at end of file
diff --git a/code/filters/news/version_2.54.mdwn b/code/filters/news/version_2.54.mdwn
new file mode 100644
index 0000000..9e74f27
--- /dev/null
+++ b/code/filters/news/version_2.54.mdwn
@@ -0,0 +1,14 @@
+filters 2.54 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix UTF-8 handling in uniencode. Closes: #[508003](http://bugs.debian.org/508003)
+     Thanks, Marius Gavrilescu.
+   * Improve layout and build process.
+     Thanks, Marius Gavrilescu.
+   * Replace fread with getchar in nethackify.
+     Thanks, Marius Gavrilescu.
+   * Fix NAME section of manpage. Closes: #[775035](http://bugs.debian.org/775035)
+     Thanks, Marius Gavrilescu.
+   * Remove SAMPLES file for deterministic builds.
+   * Makefile: Propagate input CFLAGS and LDFLAGS through to the compiler
+     to allow eg, building with hardening.
+     Thanks, Marius Gavrilescu."""]]
\ No newline at end of file
diff --git a/code/moreutils.mdwn b/code/moreutils.mdwn
index 9412705..b7cd109 100644
--- a/code/moreutils.mdwn
+++ b/code/moreutils.mdwn
@@ -57,7 +57,7 @@ The git repository can be cloned from `git://git.kitenet.net/moreutils`
 
 ## News
 
-[[!inline pages="code/moreutils/news/* and !*/Discussion" show="3"]]
+[[!inline pages="code/moreutils/news/* and !*/Discussion" show="3" rss=true]]
 
 ## TODO
 

add news item for moreutils 0.57
diff --git a/code/moreutils/news/version_0.51.mdwn b/code/moreutils/news/version_0.51.mdwn
deleted file mode 100644
index c733127..0000000
--- a/code/moreutils/news/version_0.51.mdwn
+++ /dev/null
@@ -1,9 +0,0 @@
-moreutils 0.51 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Fix ifdata to build on OS X. Thanks, Peter Eisentraut
-     Closes: #[575294](http://bugs.debian.org/575294)
-   * use docbook-xsl for building man pages. Thanks, Peter Eisentraut
-     for extensive patch set!
-     Closes: #[728831](http://bugs.debian.org/728831)
-   * Fix ifdata, ifne, parallel to build on illumos. Thanks, Gabriele Giacone
-     Closes: #[733736](http://bugs.debian.org/733736)"""]]
\ No newline at end of file
diff --git a/code/moreutils/news/version_0.57.mdwn b/code/moreutils/news/version_0.57.mdwn
new file mode 100644
index 0000000..55983db
--- /dev/null
+++ b/code/moreutils/news/version_0.57.mdwn
@@ -0,0 +1,4 @@
+moreutils 0.57 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Avoid using non-portable error() in ifdata, a portability reversion
+     introduced in 0.56."""]]
\ No newline at end of file

removed
diff --git a/blog/entry/our_beautiful_fake_histories/comment_2_62ef59dcabcec4f03dfe912069af8850._comment b/blog/entry/our_beautiful_fake_histories/comment_2_62ef59dcabcec4f03dfe912069af8850._comment
deleted file mode 100644
index 57b238e..0000000
--- a/blog/entry/our_beautiful_fake_histories/comment_2_62ef59dcabcec4f03dfe912069af8850._comment
+++ /dev/null
@@ -1,15 +0,0 @@
-[[!comment format=mdwn
- username="jordigh"
- subject="Mercurial has this..."
- date="2015-07-12T21:18:07Z"
- content="""
-Mercurial's revsets already easily allow this.
-
-First you mark your good and your bad revision as usual...
-
-hg bisect --bad -r .  # Mark current revision as bad
-hg bisect --good -r .~100 # Mark the 100th ancestor as good
-hg bisect --skip -r \"bisect('untested') and not merge()' # Skip all untested bisection commits that are not merges
-
-There are lots of good ideas in Mercurial. I don't think you are one to shy away from unpopular but interesting software. Give Mercurial a try!
-"""]]

Added a comment: Mercurial has this...
diff --git a/blog/entry/our_beautiful_fake_histories/comment_3_9502d9b26ea7fb4b8f3e1e2b572b109e._comment b/blog/entry/our_beautiful_fake_histories/comment_3_9502d9b26ea7fb4b8f3e1e2b572b109e._comment
new file mode 100644
index 0000000..9f5dee5
--- /dev/null
+++ b/blog/entry/our_beautiful_fake_histories/comment_3_9502d9b26ea7fb4b8f3e1e2b572b109e._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="jordigh"
+ subject="Mercurial has this..."
+ date="2015-07-12T21:18:36Z"
+ content="""
+Mercurial's revsets already easily allow this.
+
+First you mark your good and your bad revision as usual...
+
+hg bisect --bad -r .  # Mark current revision as bad
+
+hg bisect --good -r .~100 # Mark the 100th ancestor as good
+
+hg bisect --skip -r \"bisect('untested') and not merge()' # Skip all untested bisection commits that are not merges
+
+There are lots of good ideas in Mercurial. I don't think you are one to shy away from unpopular but interesting software. Give Mercurial a try!
+"""]]

Added a comment: Mercurial has this...
diff --git a/blog/entry/our_beautiful_fake_histories/comment_2_62ef59dcabcec4f03dfe912069af8850._comment b/blog/entry/our_beautiful_fake_histories/comment_2_62ef59dcabcec4f03dfe912069af8850._comment
new file mode 100644
index 0000000..57b238e
--- /dev/null
+++ b/blog/entry/our_beautiful_fake_histories/comment_2_62ef59dcabcec4f03dfe912069af8850._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="jordigh"
+ subject="Mercurial has this..."
+ date="2015-07-12T21:18:07Z"
+ content="""
+Mercurial's revsets already easily allow this.
+
+First you mark your good and your bad revision as usual...
+
+hg bisect --bad -r .  # Mark current revision as bad
+hg bisect --good -r .~100 # Mark the 100th ancestor as good
+hg bisect --skip -r \"bisect('untested') and not merge()' # Skip all untested bisection commits that are not merges
+
+There are lots of good ideas in Mercurial. I don't think you are one to shy away from unpopular but interesting software. Give Mercurial a try!
+"""]]

Added a comment: that is wonderful
diff --git a/blog/entry/sweet_summer/comment_1_c5d919597cea47b90f8d56342f39ad71._comment b/blog/entry/sweet_summer/comment_1_c5d919597cea47b90f8d56342f39ad71._comment
new file mode 100644
index 0000000..86320ac
--- /dev/null
+++ b/blog/entry/sweet_summer/comment_1_c5d919597cea47b90f8d56342f39ad71._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="foobarbarfoo@41160396de35c5e0eb910a6aa810b8b6f35714db"
+ nickname="foobarbarfoo"
+ subject="that is wonderful"
+ date="2015-07-12T03:33:21Z"
+ content="""
+Thank you Mr. Hess for all your work for Debian and free software. I like to read that you have a healthy and pleasant time with your family and friends. I like that you achieved something special. You live in the nature in your house with your wife, do permaculture and just take the necessary out of nature that you need. Besides the flights to conferences your footprint is quite low and you help so many people with your software. I wish you all the best, health and a good time. Thanks.
+"""]]

fix
diff --git a/blog/entry/sweet_summer.mdwn b/blog/entry/sweet_summer.mdwn
index 52148ea..0494c96 100644
--- a/blog/entry/sweet_summer.mdwn
+++ b/blog/entry/sweet_summer.mdwn
@@ -1,16 +1,16 @@
-<img src="pics/blackberrytart.jpg" alt="blackberry chocolate tart">
+[[pics/blackberrytart.jpg]]
 
 Having a wonderful summer, full of simple sweet pleasures. Mom visited
 today, and I made her this blackberry chocolate tart. Picking berries,
 swimming in the river, perfect summer day.
 
-<img scc="pics/dunetent.jpg" alt="tent in the dunes">
+[[pics/dunetent.jpg]]
 
 Earlier this summer, camped at in the dunes on Ocracoke island with many
 family and friends. Thunderstorms away across the sound flashed and
 grumbled long in the night, but mostly missed us. Jupiter and Venus in
 conjunction overhead, and the arch of the milky way completed the show.
 
-<img src="pics/beachselfie.jpg" alt="beach selfie">
+[[pics/beachselfie.jpg]]
 
 [[!tag lay]]

blog update
diff --git a/blog/entry/sweet_summer.mdwn b/blog/entry/sweet_summer.mdwn
new file mode 100644
index 0000000..52148ea
--- /dev/null
+++ b/blog/entry/sweet_summer.mdwn
@@ -0,0 +1,16 @@
+<img src="pics/blackberrytart.jpg" alt="blackberry chocolate tart">
+
+Having a wonderful summer, full of simple sweet pleasures. Mom visited
+today, and I made her this blackberry chocolate tart. Picking berries,
+swimming in the river, perfect summer day.
+
+<img scc="pics/dunetent.jpg" alt="tent in the dunes">
+
+Earlier this summer, camped at in the dunes on Ocracoke island with many
+family and friends. Thunderstorms away across the sound flashed and
+grumbled long in the night, but mostly missed us. Jupiter and Venus in
+conjunction overhead, and the arch of the milky way completed the show.
+
+<img src="pics/beachselfie.jpg" alt="beach selfie">
+
+[[!tag lay]]
diff --git a/blog/pics/beachselfie.jpg b/blog/pics/beachselfie.jpg
new file mode 100644
index 0000000..ac1d8b0
Binary files /dev/null and b/blog/pics/beachselfie.jpg differ
diff --git a/blog/pics/blackberrytart.jpg b/blog/pics/blackberrytart.jpg
new file mode 100644
index 0000000..3e69c6e
Binary files /dev/null and b/blog/pics/blackberrytart.jpg differ
diff --git a/blog/pics/dunetent.jpg b/blog/pics/dunetent.jpg
new file mode 100644
index 0000000..a9bf443
Binary files /dev/null and b/blog/pics/dunetent.jpg differ