Recent changes to this wiki:

update
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index 9741937..08e5eb1 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -10,6 +10,7 @@ challenge. It is written in Haskell.
 
 BTW, `scroll` is also a functional unix file pager, like `less` or `more`.
 
+<!-- 
 ## play `scroll`
 
 For a quick play on the web, there are two demo servers up!
@@ -19,6 +20,7 @@ For a quick play on the web, there are two demo servers up!
 
 For deeper exploration, I recommend using telnet instead. Login and
 password for telnet are both "scroll".
+-->
 
 ## install `scroll`
 
diff --git a/ocracode.mdwn b/ocracode.mdwn
index d4d7903..8f1f555 100644
--- a/ocracode.mdwn
+++ b/ocracode.mdwn
@@ -114,4 +114,4 @@ describe your camping trip to Ocracoke.
 * [[2009|blog/entry/vacation2]]
 * [[2010|blog/entry/at_the_beach]]
 * [[2011|blog/entry/summer_trips_wrapup]]
-* [[2013|blog/entry/laptop_death]]
+* [[2014|blog/entry/laptop_death]]

add screencast
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index 074cbd4..9741937 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -38,7 +38,7 @@ Scroll is also available in [NixOS](http://hydra.nixos.org/job/nixpkgs/haskell-u
 
 ## blog
 
-[[!inline pages="blog/entry/7drl_2015_* or code/scroll/news/*" archive=yes]]
+[[!inline pages="blog/entry/7drl_2015_* or code/scroll/news/* or screencasts/scroll*" archive=yes]]
 
 ## reviews
 
diff --git a/screencasts/scroll_tutorial_screencast.mdwn b/screencasts/scroll_tutorial_screencast.mdwn
new file mode 100644
index 0000000..b3f12ea
--- /dev/null
+++ b/screencasts/scroll_tutorial_screencast.mdwn
@@ -0,0 +1 @@
+<video controls src="http://downloads.kitenet.net/videos/scroll-tutorial.ogv"></video>

put US back on as crowds subside
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index ea3f878..074cbd4 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -15,6 +15,7 @@ BTW, `scroll` is also a functional unix file pager, like `less` or `more`.
 For a quick play on the web, there are two demo servers up!
 
 * EU <http://eu.scroll.joeyh.name:4242/>  -or-  `telnet eu.scroll.joeyh.name`
+* US <http://us.scroll.joeyh.name:4242/>  -or-  `telnet us.scroll.joeyh.name`
 
 For deeper exploration, I recommend using telnet instead. Login and
 password for telnet are both "scroll".

scroll downgrade
diff --git a/code.mdwn b/code.mdwn
index df6f5fd..bc27bf6 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -14,7 +14,6 @@ The stuff that's swapped into my local cache at the moment.
 [[ikiwiki-hosting]]
 [[github-backup]]
 [[shell-monad]]
-[[scroll]]
 
 ## Less active projects
 
@@ -26,6 +25,7 @@ In maintenance mode mostly, but I still have my hands in it somewhat.
 [[filters]]
 [[electrum-mnemonic]]
 [[brainfuck-monad]]
+[[scroll]]
 
 ## Past projects
 

people can't take a hint
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index ce05cf2..ea3f878 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -14,7 +14,6 @@ BTW, `scroll` is also a functional unix file pager, like `less` or `more`.
 
 For a quick play on the web, there are two demo servers up!
 
-* US <http://us.scroll.joeyh.name:4242/>  -or-  `telnet us.scroll.joeyh.name` (currently overloaded and OOMing)
 * EU <http://eu.scroll.joeyh.name:4242/>  -or-  `telnet eu.scroll.joeyh.name`
 
 For deeper exploration, I recommend using telnet instead. Login and

update
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index a5a044e..ce05cf2 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -14,7 +14,7 @@ BTW, `scroll` is also a functional unix file pager, like `less` or `more`.
 
 For a quick play on the web, there are two demo servers up!
 
-* US <http://us.scroll.joeyh.name:4242/>  -or-  `telnet us.scroll.joeyh.name`
+* US <http://us.scroll.joeyh.name:4242/>  -or-  `telnet us.scroll.joeyh.name` (currently overloaded and OOMing)
 * EU <http://eu.scroll.joeyh.name:4242/>  -or-  `telnet eu.scroll.joeyh.name`
 
 For deeper exploration, I recommend using telnet instead. Login and

nixos
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index 03f3299..a5a044e 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -32,6 +32,10 @@ and then run:
 	cabal update
 	cabal install scroll --bindir=$HOME/bin
 
+Scroll is also available in [NixOS](http://hydra.nixos.org/job/nixpkgs/haskell-updates/haskellngPackages.scroll.x86_64-linux)!
+
+	nix-env -i scroll
+
 ## blog
 
 [[!inline pages="blog/entry/7drl_2015_* or code/scroll/news/*" archive=yes]]

7drl reviews
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index 308d642..03f3299 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -54,6 +54,22 @@ and then run:
 
 > addictive .. seems like the birth of a classic -- simonkwmichael
 
+### [7drl review](http://roguetemple.com/7drl/2015/)
+
+Overall score: 2.17 out of 3
+
+> Scroll has an interesting idea but seems to fall afoul of its own
+> inventiveness. -- reviewer 1
+
+> [...] the environment is very mutable and you have to play around with it
+> in order to escape. That on its own makes this a RL worth checking out.
+> -- reviewer 2
+
+> It's somewhat fun at first, but after awhile searching combinations of
+> letters in a wall of text becomes tiresome. -- reviewer 3
+
+Many thanks to all the reviewers! --[[Joey]]
+
 ## coda
 
 [[game_designer_thoughts|scroll/thoughts]]

from https://www.atlassian.com/git/articles/10-years-of-git/
diff --git a/code/git-annex/timeline.png b/code/git-annex/timeline.png
new file mode 100644
index 0000000..7820195
Binary files /dev/null and b/code/git-annex/timeline.png differ

updae
diff --git a/code.mdwn b/code.mdwn
index 52cddd3..df6f5fd 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -24,8 +24,8 @@ In maintenance mode mostly, but I still have my hands in it somewhat.
 [[Words2Nums]]
 [[pdmenu]]
 [[filters]]
-[electrum-mnemonic](http://hackage.haskell.org/package/electrum-mnemonic)
-[brainfuck-monad](http://hackage.haskell.org/package/brainfuck-monad)
+[[electrum-mnemonic]]
+[[brainfuck-monad]]
 
 ## Past projects
 
diff --git a/code/brainfuck-monad.mdwn b/code/brainfuck-monad.mdwn
new file mode 100644
index 0000000..49108cb
--- /dev/null
+++ b/code/brainfuck-monad.mdwn
@@ -0,0 +1,3 @@
+Haskell DSL that generates brainfuck programs.
+
+[brainfuck-monad](http://hackage.haskell.org/package/brainfuck-monad)
diff --git a/code/electrum-mnemonic.mdwn b/code/electrum-mnemonic.mdwn
new file mode 100644
index 0000000..316d676
--- /dev/null
+++ b/code/electrum-mnemonic.mdwn
@@ -0,0 +1,4 @@
+A compatible re-implementation of the mnemonic used by the Electrum bitcoin
+wallet.
+
+<http://hackage.haskell.org/package/electrum-mnemonic>

update
diff --git a/contact.mdwn b/contact.mdwn
index 1d7d141..cb322fe 100644
--- a/contact.mdwn
+++ b/contact.mdwn
@@ -1,4 +1,5 @@
 * email: <id@joeyh.name>
 * gpg key: [E85A 5F63 B31D 24C1 EBF0  D81C C910 D922 2512 E3C7](http://pgp.cs.uu.nl/stats/2512E3C7.html)
-* identi.ca: <http://identi.ca/joeyh>
+* pump: <http://identi.ca/joeyh>
+* irc: joeyh (irc.oftc.net or irc.freenode.net)
 * some ways to send me a "thank you" for my work, if you're so inclined: [[thanks]]

format
diff --git a/links/interviews.mdwn b/links/interviews.mdwn
index 29f3bdf..13c3080 100644
--- a/links/interviews.mdwn
+++ b/links/interviews.mdwn
@@ -1,6 +1,7 @@
 ### interviews
 
 [2012: The Setup](http://joey.hess.usesthis.com)  
-> "When power is low, I often hack in the evenings by lantern light."  
+> "When power is low, I often hack in the evenings by lantern light."
+
 [2015: Life after Debian](https://zgrimshell.github.io/interviews-with-floss-developers-joey-hess/)  
-> "I want to build worthwhile things that might last."  
+> "I want to build worthwhile things that might last."

format
diff --git a/links/interviews.mdwn b/links/interviews.mdwn
index a5e6296..29f3bdf 100644
--- a/links/interviews.mdwn
+++ b/links/interviews.mdwn
@@ -1,6 +1,6 @@
 ### interviews
 
 [2012: The Setup](http://joey.hess.usesthis.com)  
-> "When power is low, I often hack in the evenings by lantern light."
+> "When power is low, I often hack in the evenings by lantern light."  
 [2015: Life after Debian](https://zgrimshell.github.io/interviews-with-floss-developers-joey-hess/)  
-> "I want to build worthwhile things that might last."
+> "I want to build worthwhile things that might last."  

quote
diff --git a/links/interviews.mdwn b/links/interviews.mdwn
index f14ba84..a5e6296 100644
--- a/links/interviews.mdwn
+++ b/links/interviews.mdwn
@@ -1,5 +1,6 @@
 ### interviews
 
 [2012: The Setup](http://joey.hess.usesthis.com)  
+> "When power is low, I often hack in the evenings by lantern light."
 [2015: Life after Debian](https://zgrimshell.github.io/interviews-with-floss-developers-joey-hess/)  
 > "I want to build worthwhile things that might last."

link cleanup
diff --git a/blog/about.mdwn b/blog/about.mdwn
index 9ca4a69..67df9d8 100644
--- a/blog/about.mdwn
+++ b/blog/about.mdwn
@@ -26,8 +26,6 @@ Besides the main blog, some other feeds are available:
   for stuff related to me.
 * I also have a [[pics/photoblog]] and [[screencasts]].
 
-Of course Technorati lists
-[blogs that link here](http://www.technorati.com/search/http://kitenet.net/~joey/blog).
 Also, my blog is aggregated on sites including:
 
 * [Planet Debian](http://planet.debian.org)

link
diff --git a/blog/about.mdwn b/blog/about.mdwn
index 4ce818a..9ca4a69 100644
--- a/blog/about.mdwn
+++ b/blog/about.mdwn
@@ -14,10 +14,10 @@ Besides the main blog, some other feeds are available:
 * [[archives]]
 * [[lay]] feed, which omits the technical bits
 * Some categories I blog about from time to time, including [[music]], 
-  [[unicode]], [[code]], [[haskell]] and [[wishlist]].
-* [[dwn]] feed, containing some Debian news items
+  [[unicode]], [[code]] and [[wishlist]].
 * [[howto]] feed, containing some HOWTOs.
 * [[git]] feed, posts about git
+* [[haskell]] feed, documenting my long Haskell journey.
 * [[discussion]] feed, containing discussion about pages on my wiki
 * [[foo]] feed, which contains all manner of blather and mindless link
   propigation that doesn't show up in the main feed. Kinda the blog behind

link
diff --git a/blog/about.mdwn b/blog/about.mdwn
index 7b790e7..4ce818a 100644
--- a/blog/about.mdwn
+++ b/blog/about.mdwn
@@ -14,7 +14,7 @@ Besides the main blog, some other feeds are available:
 * [[archives]]
 * [[lay]] feed, which omits the technical bits
 * Some categories I blog about from time to time, including [[music]], 
-  [[unicode]], [[code]], and [[wishlist]].
+  [[unicode]], [[code]], [[haskell]] and [[wishlist]].
 * [[dwn]] feed, containing some Debian news items
 * [[howto]] feed, containing some HOWTOs.
 * [[git]] feed, posts about git

foo
diff --git a/license.mdwn b/license.mdwn
index 6d12651..383ff5d 100644
--- a/license.mdwn
+++ b/license.mdwn
@@ -1,9 +1,6 @@
 Unless otherwise noted in an individual file, the content of this website
 is Copyright by Joey Hess and contributors, and licensed under the
-
-<a rel="license" href="http://creativecommons.org/licenses/by/4.0/">
-<img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a>
-<a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.
+<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.
 
 Source code (including specifications or data that can be used
 as source code equivilants) are dual licenced under the above license, or
@@ -12,7 +9,7 @@ the following simple permissive license:
 > Redistribution and use in source and compiled forms, with or without
 > modification, are permitted under any circumstances. No warranty.
 
-This license does not apply to the content of <https://joeyh.name/pics/>
+These license terms does not apply to the content of <https://joeyh.name/pics/>
 which is content aggregated from elsewhere, or to pages that are
 aggregating RSS etc feeds from elsewhere.
 

license
diff --git a/license.mdwn b/license.mdwn
new file mode 100644
index 0000000..6d12651
--- /dev/null
+++ b/license.mdwn
@@ -0,0 +1,40 @@
+Unless otherwise noted in an individual file, the content of this website
+is Copyright by Joey Hess and contributors, and licensed under the
+
+<a rel="license" href="http://creativecommons.org/licenses/by/4.0/">
+<img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a>
+<a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.
+
+Source code (including specifications or data that can be used
+as source code equivilants) are dual licenced under the above license, or
+the following simple permissive license:
+
+> Redistribution and use in source and compiled forms, with or without
+> modification, are permitted under any circumstances. No warranty.
+
+This license does not apply to the content of <https://joeyh.name/pics/>
+which is content aggregated from elsewhere, or to pages that are
+aggregating RSS etc feeds from elsewhere.
+
+----
+
+Note that the above is written to appease people who feel that the copyright
+regime must be taken seriously when it comes to things posted on the internet
+for the express purpose of being viewed by others on the internet.
+
+I don't subscribe to that viewpoint myself. I do enjoy the legal hack of
+copyleft licenses, as applied to free software. But, when it comes to basic
+human communications online, such as this website, I prefer to consider
+reality:
+
+To get from my server to your screen, these very words have been copied and
+re-copied dozens and dozens of times, and have been broken apart, modified,
+reassembled, used as inputs for complicated processes that produced derivative
+works and combined them with other inputs licensed under other, possibly
+conflicting licenses. This happens no matter what license anything is under.
+It's how networks and computers work.
+
+If you don't like that, you shouldn't post your stuff online. If you post your
+stuff online and think some license can prevent such things, think again.  
+I love it. Copy away!
+
diff --git a/meta.mdwn b/meta.mdwn
index 446b3d5..0f04ea4 100644
--- a/meta.mdwn
+++ b/meta.mdwn
@@ -3,6 +3,8 @@ This wiki contains [[!pagecount pages="* and !*.* and !grep/* and
 !*/Discussion"]] pages are blog entries and [[!pagecount
 pages="*/Discussion"]] are Discussion pages.
 
+It has a [[license]], if you care about that sort of thing.
+
 Broken links:
 
 [[!brokenlinks ]]

update
diff --git a/termcast.mdwn b/termcast.mdwn
index 4ab6e11..edf3229 100644
--- a/termcast.mdwn
+++ b/termcast.mdwn
@@ -3,12 +3,6 @@ termcasting is on [nethack.alt.org](http://nethack.alt.org/). Some other
 people termcast on [termcast.org](http://termcast.org/).
 
 I sometimes termcast, when I'm doing something I think may be interesting.
-I announce such termcasts at <http://identi.ca/tag/termcast>.
-
-[[!template id=note text="""
-Recent [termcasts](http://identi.ca/tag/termcast):
-[[!inline pages="internal(grep/identi.ca_posts/*termcast*)" template="microblog" show=5 feeds=no]]
-"""]]
 
 ## To see my termcasts
 
@@ -17,7 +11,7 @@ Recent [termcasts](http://identi.ca/tag/termcast):
 * Make sure your terminal is at least 80x32 in size. (I sometimes use
   127x34 too, so bigger the better.) If you see corruption, try a bigger
   size.
-* telnet [gnu.kitenet.net](telnet://gnu.kitenet.net/)
+* telnet [darkstar.kitenet.net](telnet://darkstar.kitenet.net/)
 
 [[!img screenshot.png]]
 

Vidir suggestion added.
diff --git a/code/moreutils/discussion.mdwn b/code/moreutils/discussion.mdwn
index 766e0bb..db4764a 100644
--- a/code/moreutils/discussion.mdwn
+++ b/code/moreutils/discussion.mdwn
@@ -195,6 +195,17 @@ Another possible improvement would be to automatically create needed directories
 For example, renaming dir/file to dir2/file will also create "dir2" to avoid a failing mv.
 This may be an option or a change to the default behavior, I'm not sure what's better. -- M. Poletti
 
+Sometimes I feel vidir misses chmod capabilities. I would imagine this as a switch (--chmod):
+
+$ vidir --chmod zshrc
+
+1 0644 zshrc
+
+/end example
+
+Literals would be even better. -- poyo983
+
+
 ## seddir?
 
 Throwing out ideas for a vidir implementation to support non-interactive editors like sed.  

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 eb977b2..77111c4 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 42 "watched it all, liked it" 8 "watched some, boring" 3 "too long for me" 14 "too haskell for me" 12 "not interested"]]
+[[!poll 43 "watched it all, liked it" 8 "watched some, boring" 3 "too long for me" 14 "too haskell for me" 12 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

poll vote (watched it all, liked it)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index e4b7cf1..eb977b2 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 41 "watched it all, liked it" 8 "watched some, boring" 3 "too long for me" 14 "too haskell for me" 12 "not interested"]]
+[[!poll 42 "watched it all, liked it" 8 "watched some, boring" 3 "too long for me" 14 "too haskell for me" 12 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

Added a comment
diff --git a/blog/entry/7drl_2015_day_1_groundwork/comment_2_4043f8cd2a4ba93b43fa77ddca43f892._comment b/blog/entry/7drl_2015_day_1_groundwork/comment_2_4043f8cd2a4ba93b43fa77ddca43f892._comment
new file mode 100644
index 0000000..c15bd9b
--- /dev/null
+++ b/blog/entry/7drl_2015_day_1_groundwork/comment_2_4043f8cd2a4ba93b43fa77ddca43f892._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl51jMpDe22wrWROMQSECT649TZEsbUNfE"
+ nickname="Mikolaj"
+ subject="comment 2"
+ date="2015-04-04T13:36:28Z"
+ content="""
+Heh, re monster type signature, in the just released v0.4.101.0 this and similar types are somewhat simpler and better documented:
+
+    loopSer :: (MonadAtomic m, MonadServerReadRequest m) => COps -> DebugModeSer -> (FactionId -> ChanServer ResponseUI RequestUI -> IO ()) -> (FactionId -> ChanServer ResponseAI RequestAI -> IO ()) -> m ()
+
+see <http://hackage.haskell.org/package/LambdaHack-0.4.101.0/docs/Game-LambdaHack-Server-LoopServer.html>.
+
+But you are right, for anything but a re-skin, the engine would surely need to be extended, which is a week of experiments and clueless questions, before you even know which end to approach. :)
+
+BTW., your game is breathtakingly brilliant and the dev diary is fun too. I hope to see more from you in the future. Haskell is endless fun: the backlog of intriguing features and libs you'd like to learn and apply grows year after year.
+"""]]

foo
diff --git a/blog/entry/I_am_ArchiveTeam.mdwn b/blog/entry/I_am_ArchiveTeam.mdwn
index a482b9e..0476af8 100644
--- a/blog/entry/I_am_ArchiveTeam.mdwn
+++ b/blog/entry/I_am_ArchiveTeam.mdwn
@@ -22,3 +22,5 @@ and/or I'm bored.
 
 (Rumors of me being the hand model for ArchiveTeam are, however,
 unsubstantiated.)
+
+[Relevant XKCD](http://xkcd.com/1506/)

update
diff --git a/blog/entry/I_am_ArchiveTeam.mdwn b/blog/entry/I_am_ArchiveTeam.mdwn
index 9677e20..a482b9e 100644
--- a/blog/entry/I_am_ArchiveTeam.mdwn
+++ b/blog/entry/I_am_ArchiveTeam.mdwn
@@ -19,3 +19,6 @@ internet meme-land. It's a 0.1% project for me, and has grown into a
 well-oiled machine, albeit one that shouldn't need to exist. I only get
 involved these days when there's another crazy internet silo fire drill
 and/or I'm bored.
+
+(Rumors of me being the hand model for ArchiveTeam are, however,
+unsubstantiated.)

foo
diff --git a/blog/entry/I_am_ArchiveTeam.mdwn b/blog/entry/I_am_ArchiveTeam.mdwn
index 75a7eb9..9677e20 100644
--- a/blog/entry/I_am_ArchiveTeam.mdwn
+++ b/blog/entry/I_am_ArchiveTeam.mdwn
@@ -1,5 +1,3 @@
-[[meta title="'I am ArchiveTeam'"]]
-
 This seems as good a day as any to mention that I am a founding member of
 ArchiveTeam.
 

blog update
diff --git a/blog/entry/I_am_ArchiveTeam.mdwn b/blog/entry/I_am_ArchiveTeam.mdwn
new file mode 100644
index 0000000..75a7eb9
--- /dev/null
+++ b/blog/entry/I_am_ArchiveTeam.mdwn
@@ -0,0 +1,23 @@
+[[meta title="'I am ArchiveTeam'"]]
+
+This seems as good a day as any to mention that I am a founding member of
+ArchiveTeam.
+
+<a href="http://archiveteam.org/"><img src="http://archiveteam.org/images/e/e6/Archiveteam.jpg" alt="ArchiveTeam logo"></a>
+
+Way back, when Geocities was closing down, I was one of a small
+rag-tag group who saved a copy of most of it. That snapshot has since
+generated more publicity than most other projects I've worked on.
+I've heard many heartwarning stories of it being the only remaining
+copy of baby pictures and writings of deceased friends, and so on.
+It's even been the subject of
+[serious academic study as outlined in this talk](http://cdn.media.ccc.de/congress/2014/h264-hd/31c3-6373-en-de-The_Only_Thing_We_Know_About_Cyberspace_Is_That_Its_640x480_hd.mp4),
+which is pretty awesome.
+
+<img src="https://pbs.twimg.com/media/CAMZihSVAAEHyAa.jpg:small" alt="Jason Scott in full stage regalia">
+
+I'm happy to let this guy be the public face of ArchiveTeam in
+internet meme-land. It's a 0.1% project for me, and has grown into a
+well-oiled machine, albeit one that shouldn't need to exist. I only get
+involved these days when there's another crazy internet silo fire drill
+and/or I'm bored.

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 5496c2a..e4b7cf1 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 40 "watched it all, liked it" 8 "watched some, boring" 3 "too long for me" 14 "too haskell for me" 12 "not interested"]]
+[[!poll 41 "watched it all, liked it" 8 "watched some, boring" 3 "too long for me" 14 "too haskell for me" 12 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

add news item for scroll 1.20150323
diff --git a/code/scroll/news/version_1.20150323.mdwn b/code/scroll/news/version_1.20150323.mdwn
new file mode 100644
index 0000000..c2087b5
--- /dev/null
+++ b/code/scroll/news/version_1.20150323.mdwn
@@ -0,0 +1,4 @@
+scroll 1.20150323 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix a minor bug when moving over punctuation that was not swallowed.
+     (This didn't affect gameplay.)"""]]
\ No newline at end of file

trim
diff --git a/pics/misc/brain.png b/pics/misc/brain.png
index f0cdf57..d5f62f6 100644
Binary files a/pics/misc/brain.png and b/pics/misc/brain.png differ

add
diff --git a/pics/misc/brain.png b/pics/misc/brain.png
new file mode 100644
index 0000000..f0cdf57
Binary files /dev/null and b/pics/misc/brain.png differ

review
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index f5cae78..308d642 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -52,6 +52,8 @@ and then run:
 > great game once you get the hang of it  
 > I <3 Haskell :D -- Anon
 
+> addictive .. seems like the birth of a classic -- simonkwmichael
+
 ## coda
 
 [[game_designer_thoughts|scroll/thoughts]]

add news item for scroll 1.20150314
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index e57bc94..f5cae78 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -34,7 +34,7 @@ and then run:
 
 ## blog
 
-[[!inline pages="blog/entry/7drl_2015_*" archive=yes]]
+[[!inline pages="blog/entry/7drl_2015_* or code/scroll/news/*" archive=yes]]
 
 ## reviews
 
diff --git a/code/scroll/news/version_1.20150314.mdwn b/code/scroll/news/version_1.20150314.mdwn
new file mode 100644
index 0000000..287d6af
--- /dev/null
+++ b/code/scroll/news/version_1.20150314.mdwn
@@ -0,0 +1,9 @@
+scroll 1.20150314 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * This is a post-7drl release that does not change any gameplay.
+   * Support use as a pager, with input piped in on stdin, as long
+     as the unix module is available.
+   * Rename Setup.hs since cabal uses that name.
+     Thanks to Sergei Trofimovich of Gentoo, which has packaged scroll!
+   * Don't crash on exceedingly small input files when being used as a
+     pager."""]]
\ No newline at end of file

response
diff --git a/blog/entry/shell_monad/comment_2_08df15c64a43affe03a6ee4e77dc7a30._comment b/blog/entry/shell_monad/comment_2_08df15c64a43affe03a6ee4e77dc7a30._comment
new file mode 100644
index 0000000..f113de5
--- /dev/null
+++ b/blog/entry/shell_monad/comment_2_08df15c64a43affe03a6ee4e77dc7a30._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2015-03-14T17:34:23Z"
+ content="""
+Thanks for reporting, I'll fix this in 0.6.3.
+
+The best way to report bugs in shell-monad currently is to email me.
+"""]]

img
diff --git a/blog/entry/7drl_2015_day_7_scroll_success.mdwn b/blog/entry/7drl_2015_day_7_scroll_success.mdwn
index bc6b54d..0a41ec6 100644
--- a/blog/entry/7drl_2015_day_7_scroll_success.mdwn
+++ b/blog/entry/7drl_2015_day_7_scroll_success.mdwn
@@ -18,4 +18,6 @@ code and features a playable character.
 I have six hours until my 7drl is officially over, but I'm done! Success!
 You can download the code, play, etc, at [[Scroll's homepage|code/scroll]]
 
+<a href="http://joeyh.name/code/scroll/"><img src="https://joeyh.name/code/scroll/title.png"></a>
+
 [[!tag 7drl code/scroll]]

scroll fin
diff --git a/blog/entry/7drl_2015_day_7_scroll_success.mdwn b/blog/entry/7drl_2015_day_7_scroll_success.mdwn
new file mode 100644
index 0000000..bc6b54d
--- /dev/null
+++ b/blog/entry/7drl_2015_day_7_scroll_success.mdwn
@@ -0,0 +1,21 @@
+A frantic last day of work on [[code/Scroll]].
+
+Until 3 am last night, I was working on adding a new procedurally generated
+level.
+
+This morning, fixed two major bugs reported by playesters overnight. Also
+fixed crashes on small screens and got the viewport to scroll. Added a victory
+animation in time for lunch.
+
+After lunch, more level generation work. Wasted an entire hour tracking
+down a bug in level gen I introduced last night, when I was bad and didn't
+create a data type to express an idea. Added a third type of generated
+level, with its own feel.
+
+Finished up with a level selection screen, which needed just 47 lines of
+code and features a playable character.
+
+I have six hours until my 7drl is officially over, but I'm done! Success!
+You can download the code, play, etc, at [[Scroll's homepage|code/scroll]]
+
+[[!tag 7drl code/scroll]]
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index 3f9c906..e57bc94 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -1,3 +1,5 @@
+[[scroll/title.png]]
+
 In `scroll`, you're a bookworm that's stuck on a scroll. You have to
 dodge between words and use spells to make your way down the page as the
 scroll is read. Go too slow and you'll get wound up in the scroll and
@@ -18,7 +20,17 @@ For a quick play on the web, there are two demo servers up!
 For deeper exploration, I recommend using telnet instead. Login and
 password for telnet are both "scroll".
 
-Code coming soon for local play...
+## install `scroll`
+
+[Git repository](http://git.joeyh.name/?p=scroll.git;a=summary)
+
+Requires ncurses, on Linux or Similar.
+
+To build, first install the [Haskell Platform](http://www.haskell.org/platform/),
+and then run:
+
+	cabal update
+	cabal install scroll --bindir=$HOME/bin
 
 ## blog
 
@@ -30,8 +42,16 @@ Code coming soon for local play...
 > for ten minutes, you start thinking you're a worm looking for holes....
 > :-) -- Anna
 
+> Entertaining and addictive !  Thanks ! -- Anon
+
 > I really enjoyed munching my way through gplv2 -- Chris
 
+> this has been possibly the first game I've played using telnet that didn't
+> make me want to shoot my face off -- Anon
+
+> great game once you get the hang of it  
+> I <3 Haskell :D -- Anon
+
 ## coda
 
 [[game_designer_thoughts|scroll/thoughts]]
diff --git a/code/scroll/thoughts.mdwn b/code/scroll/thoughts.mdwn
index 70bb39a..8ce1599 100644
--- a/code/scroll/thoughts.mdwn
+++ b/code/scroll/thoughts.mdwn
@@ -1,6 +1,16 @@
 HERE BE SPOLIERS
 
-A few random bits about the game design. 
+A few random bits about the game design etc.
+
+* This is my first roguelike and my first 7drl, and the first game I wrote
+  since days of BASIC. (Not counting some MOO engines.) Haskell made this
+  a much different development experience than I remember. It was a blast!
+
+* Some players find the limitations on movement when the worm has swallowed
+  letters to be confusing. There is not a great rationalle for it that fits
+  into the game world. It was necessary to make the game sufficiently hard.
+  It might have been better to have letters be things you can swallow and
+  move around with, but for whatever reason, you don't want to.
 
 * The way that the end-game and winning plays out was a not-quite accident.
   At first I had the View contain a list of status messages, but when I
@@ -12,19 +22,52 @@ A few random bits about the game design.
 * It's possible for two spells to share overlapping components, or even
   for a single spell component to cast multiple spells at once. This was
   an accident, but it simplified the UI and data structires, and I liked
-  the possibilities,  so I kept it. It may allow for NEW farming in some
-  situations.
+  the possibilities,  so I kept it.
+  
+* NEW farming may be possible in some situations. Call it a feature.
 
 * The scroll is not physically right when flipped; the ragged bits should
   move to the other side. It's just too difficult to make semi-procedurally
   generated content that is interesting to read and that would fit in
-  such a scroll geometry, for me to be able to do that. (I might have
-  been able to do it if the back of the scroll were entirely limited to
-  Joyce, but that seemed too cruel and I added the Joyce content generator
-  too late.)
+  such a scroll geometry, for me to be able to do that. 
+  
+  (I might have been able to do it if the back of the scroll were entirely
+  limited to Joyce, but that seemed too cruel and I added the Joyce content
+  generator too late. Also, a true inversion would make thinking about
+  where to dive harder.)
 
-* Some players find the limitations on movement when the worm has swallowed
-  letters to be confusing. There is not a great rationalle for it that fits
-  into the game world. It was necessary to make the game sufficiently hard.
-  It might have been better to have letters be things you can swallow and
-  move around, but for whatever reason, you don't want to.
+  Also, it's physically impossible for a rolling up scroll to crush you
+  inside itself from both sides. Once side would really be safe if this
+  were real life. ;)
+
+* I went in with a basic game design, but I thought of diving to the other
+  side during early development. The nice thing about it is that if one
+  side gets the player irrepairably stuck, the other side probably offers a
+  way past. Since the level generation doesn't ensure a path through a
+  level, this is a very good thing!
+
+* I also didn't think up the crushed by the scroll mechanic to drive the
+  player onward until I had a scroll drawn onscreen with the player
+  moving in it. I was very happy that this gave a pace to the game,
+  similar to how hunger works in other roguelikes, but more visual, and
+  that the final "scroll rolls up" endgame fell out for nearly free.
+
+* The level generation, such as it is, was a series of happy accidents.
+  All I was sure about was the GPL would be in the mix. Given how classic
+  the source material used is, I wanted to keep close to it, rather than
+  scrambling it completely, so that it could still be enjoyed as the game
+  was played. At the same time, there is a fair amount of subtle randomness
+  going on, so there are many possible different games of scroll.
+  
+  Different texts admit different methods of randomization.
+
+  Kafka's _Metamorphasis_ would have been **utterly perfect** material,
+  but it was too linear to work well.
+
+> One morning, when Gregor Samsa woke from troubled dreams, he found himself
+> transformed in his bed into a horrible vermin. He lay on his armour-like
+> back, and if he lifted his head a little he could see his brown belly, slightly
+> domed and divided by arches into stiff sections. The bedding was hardly able to
+> cover it and seemed ready to slide off any moment. His many legs, pitifully thin
+> compared with the size of the rest of him, waved about helplessly as he
+> looked.
diff --git a/code/scroll/title.png b/code/scroll/title.png
new file mode 100644
index 0000000..07c77d8
Binary files /dev/null and b/code/scroll/title.png differ

format
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index 96c8230..3f9c906 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -12,16 +12,11 @@ BTW, `scroll` is also a functional unix file pager, like `less` or `more`.
 
 For a quick play on the web, there are two demo servers up!
 
-* US <http://us.scroll.joeyh.name:4242/>
-* EU <http://eu.scroll.joeyh.name:4242/>
+* US <http://us.scroll.joeyh.name:4242/>  -or-  `telnet us.scroll.joeyh.name`
+* EU <http://eu.scroll.joeyh.name:4242/>  -or-  `telnet eu.scroll.joeyh.name`
 
-For deeper exploration, I recommend using telnet instead.
-
-	telnet us.scroll.joeyh.name
-
-	telnet eu.scroll.joeyh.name
-
-(Login and Password are both "scroll")
+For deeper exploration, I recommend using telnet instead. Login and
+password for telnet are both "scroll".
 
 Code coming soon for local play...
 

fix
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index 6ded2fa..96c8230 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -17,8 +17,9 @@ For a quick play on the web, there are two demo servers up!
 
 For deeper exploration, I recommend using telnet instead.
 
-> telnet us.scroll.joeyh.name
-> telnet eu.scroll.joeyh.name
+	telnet us.scroll.joeyh.name
+
+	telnet eu.scroll.joeyh.name
 
 (Login and Password are both "scroll")
 

fmt
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index 6802d4a..6ded2fa 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -3,7 +3,7 @@ dodge between words and use spells to make your way down the page as the
 scroll is read. Go too slow and you'll get wound up in the scroll and
 crushed.
 
-Scroll was developed in 7 days during the 2015 [7drl](http://7drl.org/)
+`scroll` was developed in 7 days during the 2015 [7drl](http://7drl.org/)
 challenge. It is written in Haskell.
 
 BTW, `scroll` is also a functional unix file pager, like `less` or `more`.
@@ -38,4 +38,4 @@ Code coming soon for local play...
 
 ## coda
 
-[[game_designer_thoughts|spell/thoughts]]
+[[game_designer_thoughts|scroll/thoughts]]

typo
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index dca511b..6802d4a 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -17,7 +17,7 @@ For a quick play on the web, there are two demo servers up!
 
 For deeper exploration, I recommend using telnet instead.
 
-> telnet us.scroll.joeyh.name`
+> telnet us.scroll.joeyh.name
 > telnet eu.scroll.joeyh.name
 
 (Login and Password are both "scroll")

blog and srcoll website update
diff --git a/blog/entry/7drl_2015_day_6_must_add_more.mdwn b/blog/entry/7drl_2015_day_6_must_add_more.mdwn
new file mode 100644
index 0000000..912054e
--- /dev/null
+++ b/blog/entry/7drl_2015_day_6_must_add_more.mdwn
@@ -0,0 +1,33 @@
+Last night I put up a telnet server and web interface to play a demo of
+scroll and send me playtester feedback, and I've gotten that *almost* solid
+today. **[Try it!](https://joeyh.name/code/scroll/)**
+
+Today was a scramble to add more features to [[code/Scroll]] and fix bugs.
+The game still needs some balancing, and generally seems a little too hard,
+so added a couple more spells, and a powerup feature to make it easier.
+
+Added a way to learn new spells. Added a display of spell inventory on 'i'.
+For that, I had to write a quick windowing system (20 lines of code).
+
+Added a system for ill effects from eating particular letters.
+Interestingly, since such a letter is immediately digested, it doesn't
+prevent the worm from moving forwards. So, the ill effects
+can be worth it in some situations. Up to the player to decide.
+
+I'm spending a lot of time now looking at letter frequency historgrams to
+decide which letter to use for a new feature. Since I've several times
+accidentially used the same letter for two different things (most
+amusingly, I assigned 'k' to a spell, forgetting it was movement), I
+refactored all the code to have a single `charSet` which defines every
+letter and what it's used for, be that movement, control, spell casting,
+or ill effects. I'd *like* to use that to further randomize which letters
+are used for spell components, out of a set that have around the same
+frequency. However, I doubt that I'll have time to do that.
+
+In the final push tonight/tomorrow, I hope to add an additional kind of
+level or two, make the curses viewport scroll when necessary instead of
+crashing, and hopefully work on game balance/playtester feedback.
+
+I've written ~2800 lines of code so far this week!
+
+[[!tag 7drl code/scroll]]
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index 8f1564c..dca511b 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -1,5 +1,41 @@
-My entry in the 2015 [7drl](http://7drl.org/) challenge.
+In `scroll`, you're a bookworm that's stuck on a scroll. You have to
+dodge between words and use spells to make your way down the page as the
+scroll is read. Go too slow and you'll get wound up in the scroll and
+crushed.
 
-Code and online demo coming soon...
+Scroll was developed in 7 days during the 2015 [7drl](http://7drl.org/)
+challenge. It is written in Haskell.
 
-[[!inline pages="blog/entry/7drl_2015_*"]]
+BTW, `scroll` is also a functional unix file pager, like `less` or `more`.
+
+## play `scroll`
+
+For a quick play on the web, there are two demo servers up!
+
+* US <http://us.scroll.joeyh.name:4242/>
+* EU <http://eu.scroll.joeyh.name:4242/>
+
+For deeper exploration, I recommend using telnet instead.
+
+> telnet us.scroll.joeyh.name`
+> telnet eu.scroll.joeyh.name
+
+(Login and Password are both "scroll")
+
+Code coming soon for local play...
+
+## blog
+
+[[!inline pages="blog/entry/7drl_2015_*" archive=yes]]
+
+## reviews
+
+> When you start reading on your kindle after playing your game
+> for ten minutes, you start thinking you're a worm looking for holes....
+> :-) -- Anna
+
+> I really enjoyed munching my way through gplv2 -- Chris
+
+## coda
+
+[[game_designer_thoughts|spell/thoughts]]
diff --git a/code/scroll/thoughts.mdwn b/code/scroll/thoughts.mdwn
new file mode 100644
index 0000000..70bb39a
--- /dev/null
+++ b/code/scroll/thoughts.mdwn
@@ -0,0 +1,30 @@
+HERE BE SPOLIERS
+
+A few random bits about the game design. 
+
+* The way that the end-game and winning plays out was a not-quite accident.
+  At first I had the View contain a list of status messages, but when I
+  realized it would be neat for the bookworm to be able to interact with
+  them, I had to rework the data structure to let the victory condition work.
+
+  [[!img endgame.png]]
+
+* It's possible for two spells to share overlapping components, or even
+  for a single spell component to cast multiple spells at once. This was
+  an accident, but it simplified the UI and data structires, and I liked
+  the possibilities,  so I kept it. It may allow for NEW farming in some
+  situations.
+
+* The scroll is not physically right when flipped; the ragged bits should
+  move to the other side. It's just too difficult to make semi-procedurally
+  generated content that is interesting to read and that would fit in
+  such a scroll geometry, for me to be able to do that. (I might have
+  been able to do it if the back of the scroll were entirely limited to
+  Joyce, but that seemed too cruel and I added the Joyce content generator
+  too late.)
+
+* Some players find the limitations on movement when the worm has swallowed
+  letters to be confusing. There is not a great rationalle for it that fits
+  into the game world. It was necessary to make the game sufficiently hard.
+  It might have been better to have letters be things you can swallow and
+  move around, but for whatever reason, you don't want to.

thread
diff --git a/blog/entry/7drl_2015_day_5_type_directed_spell_system_development.mdwn b/blog/entry/7drl_2015_day_5_type_directed_spell_system_development.mdwn
index 85d6e46..24c0a63 100644
--- a/blog/entry/7drl_2015_day_5_type_directed_spell_system_development.mdwn
+++ b/blog/entry/7drl_2015_day_5_type_directed_spell_system_development.mdwn
@@ -87,3 +87,7 @@ interesting ideas, and implement them quickly.
 Just what I need when writing a roguelike in just 7 days!
 
 [[!tag haskell 7drl code/scroll]]
+
+----
+
+[Fun comment thread on reddit](https://www.reddit.com/r/haskell/comments/2yqwgi/type_directed_spell_system_development/)

remove haskell tag from not very haskell posts
diff --git a/blog/entry/7drl_2015_day_2_level_generation_and_game_concept.mdwn b/blog/entry/7drl_2015_day_2_level_generation_and_game_concept.mdwn
index 94815f9..24af9db 100644
--- a/blog/entry/7drl_2015_day_2_level_generation_and_game_concept.mdwn
+++ b/blog/entry/7drl_2015_day_2_level_generation_and_game_concept.mdwn
@@ -1,4 +1,4 @@
-[[!tag haskell 7drl code/scroll]]
+[[!tag 7drl code/scroll]]
 
 Much as I want to get my `@` displayed and moving around screen,
 last night and today have focused on level generation instead.
diff --git a/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn b/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn
index 22deff0..5c7fddf 100644
--- a/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn
+++ b/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn
@@ -39,4 +39,4 @@ to give that surprise away.
 But, the other thing about Scroll is that it's
 `scroll`, a completely usable (if rather difficult..) Unix pager!
 
-[[!tag haskell 7drl code/scroll]]
+[[!tag 7drl code/scroll]]

add
diff --git a/code/scroll/endgame.png b/code/scroll/endgame.png
new file mode 100644
index 0000000..69f79e1
Binary files /dev/null and b/code/scroll/endgame.png differ

blog
diff --git a/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn b/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn
index b419688..22deff0 100644
--- a/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn
+++ b/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn
@@ -34,7 +34,9 @@ explore in writing Scroll.
 As to the text that fills the scroll, it's broadly procedurally generated,
 in what I hope are unusual and repeatedly surprising (and amusing)
 ways. I'm not showing any screenshots of the real text, because I don't want
-to give that surprise away. But, the other thing about Scroll is that it's
+to give that surprise away. 
+
+But, the other thing about Scroll is that it's
 `scroll`, a completely usable (if rather difficult..) Unix pager!
 
 [[!tag haskell 7drl code/scroll]]
diff --git a/blog/entry/7drl_2015_day_5_type_directed_spell_system_development.mdwn b/blog/entry/7drl_2015_day_5_type_directed_spell_system_development.mdwn
new file mode 100644
index 0000000..85d6e46
--- /dev/null
+++ b/blog/entry/7drl_2015_day_5_type_directed_spell_system_development.mdwn
@@ -0,0 +1,89 @@
+I want my [[7drl game Scroll|code/Scroll]] to have lots of interesting spells.
+So, as I'm designing its spell system, I've been looking at the types, and
+considering the whole universe of possible spells that fit within the
+constraints of the types.
+
+My first throught was that a spell would be a function from `World -> World`.
+That allows any kind of spell that manipulates the game map. Like, for
+instance a "whiteout" that projects a stream of whitespace from the
+player's mouth.
+
+Since Scroll has a state monad, I quickly generalized that; making spell
+actions a state monad `M ()`, which lets spells reuse other monadic actions, 
+and affect the whole game state, including the player. Now I could write
+a spell like "teleport", or "grow".
+
+But it quickly became apparent this was too limiting: While spells could change
+the World map, the player, and even change the list of supported spells, they
+had no way to prompting for input.
+
+I tried a few types of the `Event -> M ()` variety, but they were all too
+limiting. Finally, I settled on this type for spell actions:
+`M NextStep -> M NextStep`. 
+
+And then I spent 3 hours exploring the universe of spells that type allows!
+To understand them, it helps to see what a NextStep is:
+
+[[!format haskell """
+type Step = Event -> M NextStep
+data NextStep = NextStep View (Maybe Step)
+"""]]
+
+Since `NextStep` is a continuation, spells take the original continuation,
+and can not only modify the game state, but can return an altered
+continuation. Such as one that prompts for input before performing the
+spell, and then calls the original continuation to get on with the game.
+
+That let me write "new", a most interesting spell, that lets the player
+add a new way to cast an existing spell. Spells are cast using ingredients, 
+and so this prompts for a new ingredient to cast a spell. (I hope that
+"new farming" will be one mode of play to possibly win [[code/Scroll]].)
+
+And, it lets me write spells that fail in game-ending ways. (Ie, "genocide @").
+A spell can cause the game to end by returning a continuation that
+has `Nothing` as its next step.
+
+Even better, I could write spells that return a continuation that contains a
+forked background task, using the 66 line contiuation based threading system I
+built in [[day_3|7drl_2015_day_3_movement_at_last]]. This allows writing lots
+of fun spells that have an effect that lasts for a while. Things like letting
+the player quickly digest letters they eat, or slow down the speed of
+events.
+
+And then I thought of "dream". This spell stores the input continuation and
+game state, and returns a modified continuation that lets the game continue
+until it ends, and then restores from the point it saved. So, the player dreams
+they're playing, and wakes back up where they cast the spell. A wild spell,
+which can have different variants, like precognitive dreams where the same
+random numbers are used as will be used upon awaking, or dreams where
+knowledge carries back over to the real world in different ways.
+(Supports Inception too..) 
+
+Look how easy it was to implement dreaming,
+in this game that didn't have any notion of "save" or "restore"!
+
+[[!format haskell """
+runDream :: M NextStep -> M NextStep -> (S -> S) -> M NextStep
+runDream sleepcont wakecont wakeupstate = go =<< sleepcont
+   where
+         go (NextStep v ms) = return $ NextStep v $ Just $
+	 	maybe wake (go <=<) ms
+         wake _evt = do
+                 modify wakeupstate
+                 wakecont
+"""]]
+
+I imagine that, if I were not using Haskell, I'd have just made the spell
+be an action, that can do IO in arbitrary ways. Such a spell system can
+of course do everything I described above and more. But, I think that
+using a general IO action is so broad that it hides the interesting
+possibilities like "dream".
+
+By starting with a limited type for spells, and exploring toward
+more featureful types, I was able to think about the range of
+possibilities of spells that each type allowed, be inspired with
+interesting ideas, and implement them quickly.
+
+Just what I need when writing a roguelike in just 7 days!
+
+[[!tag haskell 7drl code/scroll]]

wording
diff --git a/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn b/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn
index 92f8919..b419688 100644
--- a/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn
+++ b/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn
@@ -9,12 +9,12 @@ learning spells, and to balance out the game difficulty.
 
 I haven't quite said what [[code/Scroll]] is about yet, let's fix that:
 
-In Scroll, you're a bookworm that's marooned on a scroll. You have to
+In Scroll, you're a bookworm that's stuck on a scroll. You have to
 dodge between words and use spells to make your way down the page as the
 scroll is read. Go too slow and you'll get wound up in the scroll and
 crushed.
 
-So, the player is multiple chars in size (size is the player's only stat),
+The character is multiple chars in size (size is the worm's only stat),
 and the worm interacts with the scroll in lots of ways, like
 swallowing letters, or diving through a hole to the other side of the
 scroll. While it can swallow some letters, if it gets too full, it can't

blog
diff --git a/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn b/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn
new file mode 100644
index 0000000..92f8919
--- /dev/null
+++ b/blog/entry/7drl_2015_day_4_coding_through_exhaustion.mdwn
@@ -0,0 +1,40 @@
+Slow start today; I was pretty exhausted after yesterday and last night's
+work. Somehow though, I got past the burn and made major progress today.
+
+All the complex movement of both the player and the scroll is finished now,
+and all that remains is to write interesting spells, and a system for
+learning spells, and to balance out the game difficulty.
+
+----
+
+I haven't quite said what [[code/Scroll]] is about yet, let's fix that:
+
+In Scroll, you're a bookworm that's marooned on a scroll. You have to
+dodge between words and use spells to make your way down the page as the
+scroll is read. Go too slow and you'll get wound up in the scroll and
+crushed.
+
+So, the player is multiple chars in size (size is the player's only stat),
+and the worm interacts with the scroll in lots of ways, like
+swallowing letters, or diving through a hole to the other side of the
+scroll. While it can swallow some letters, if it gets too full, it can't
+move forward anymore, so letters are mostly consumed to be used as spell
+components.
+
+I think that I will manage to get away without adding any kind of monsters
+to the game; the scroll (and whoever is reading it) is the antagonist.
+
+As I'm writing this very post, I'm imagining the worm wending its way through
+my paragraphs. This dual experience of text, where you're both reading its
+content and hyper-aware of its form, is probably the main thing I wanted to
+explore in writing Scroll.
+
+[[!img code/scroll/1st_screenshot.png]]
+
+As to the text that fills the scroll, it's broadly procedurally generated,
+in what I hope are unusual and repeatedly surprising (and amusing)
+ways. I'm not showing any screenshots of the real text, because I don't want
+to give that surprise away. But, the other thing about Scroll is that it's
+`scroll`, a completely usable (if rather difficult..) Unix pager!
+
+[[!tag haskell 7drl code/scroll]]
diff --git a/code/scroll/1st_screenshot.png b/code/scroll/1st_screenshot.png
new file mode 100644
index 0000000..62b2638
Binary files /dev/null and b/code/scroll/1st_screenshot.png differ

Added a comment: Issue tracker anywhere?
diff --git a/blog/entry/shell_monad/comment_1_d71ef4bed2b7ddfc92db8f0ff08464c0._comment b/blog/entry/shell_monad/comment_1_d71ef4bed2b7ddfc92db8f0ff08464c0._comment
new file mode 100644
index 0000000..78befed
--- /dev/null
+++ b/blog/entry/shell_monad/comment_1_d71ef4bed2b7ddfc92db8f0ff08464c0._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmdoZwTJoqBSrwWtAgFfNoD3zU8h7a0nzI"
+ nickname="Ville"
+ subject="Issue tracker anywhere?"
+ date="2015-03-10T12:52:47Z"
+ content="""
+Do you have an issue tracker for shell monad? It seems that 
+
+     ifCmd (test (TDirExists (\"MCQ/.git\"))) .. ..
+
+generates code 
+
+     if test \(-d 'MCQ/.git'\)
+
+instead of the working
+
+    if test \( -d 'MCQ/.git' \)
+
+or 
+
+    if [ -d 'MCQ/.git' ]
+
+"""]]

typo
diff --git a/blog/entry/7drl_2015_day_3_movement_at_last.mdwn b/blog/entry/7drl_2015_day_3_movement_at_last.mdwn
index dcb0fa4..169b4b1 100644
--- a/blog/entry/7drl_2015_day_3_movement_at_last.mdwn
+++ b/blog/entry/7drl_2015_day_3_movement_at_last.mdwn
@@ -67,7 +67,7 @@ endThread = nextStep Nothing
 background :: M NextStep -> M NextStep
 background job = fork job continue
 
-demo :: M.NextStep
+demo :: M NextStep
 demo = do
 	showMessage "foo"
 	background $ next $ const $

blog
diff --git a/blog/entry/7drl_2015_day_3_movement_at_last.mdwn b/blog/entry/7drl_2015_day_3_movement_at_last.mdwn
new file mode 100644
index 0000000..dcb0fa4
--- /dev/null
+++ b/blog/entry/7drl_2015_day_3_movement_at_last.mdwn
@@ -0,0 +1,78 @@
+[[!tag haskell 7drl code/scroll]]
+
+Got the player moving in the map! And, got the map to be deadly in its own
+special way.
+
+[[!format haskell """
+        HeadCrush -> do
+                showMessage "You die."
+                endThread
+"""]]
+
+Even winning the game is implemented. The game has a beginning, a middle,
+and an end.
+
+I left the player movement mostly unconstrained, today, while I was working
+on things to do with the end of the game, since that makes it easier to
+play through and test them. Tomorrow, I will turn on fully constrained
+movement (an easy change), implement inventory (which is very connected to
+movement constraints in [[code/Scroll]]), and hope to 
+start on the spell system too.
+
+----
+
+At this point, Scroll is 622 lines of code, including content.
+Of which, I notice, fully 119 are types and type classes.
+
+Only 4 days left! Eep! I'm very glad that scroll's central antagonist is
+already written. I don't plan to add other creatures, which will save some
+time.
+
+----
+
+Last night as I was drifting off to sleep, it came to me a way
+to implement my own threading system for my roguelike. Since
+time in a roguelike happens in discrete ticks, as the player takes
+each action, normal OS threads are not suitable. And in my case,
+I'm doing everything in pure code anyway and certianly cannot fork
+off a thread for some background job.
+
+But, since I'm using continuation passing style, I can just write
+my own `fork`, that takes two continuations and combines them,
+causing both to be run on each tick, and recursing to handle combining
+the resulting continuations.
+
+It was really quite simple to implement. Typechecked on the first try even!
+
+[[!format haskell """
+fork :: M NextStep -> M NextStep -> M NextStep
+fork job rest = do
+        jn <- job
+        rn <- rest
+        runthread jn rn
+  where
+        runthread (NextStep _ (Just contjob)) (NextStep v (Just contr)) =
+                return $ NextStep v $ Just $ \i -> do
+                        jn <- contjob i
+                        rn <- contr i
+                        runthread jn rn
+        runthread (NextStep _ Nothing) (NextStep v (Just contr)) =
+                return $ NextStep v (Just contr)
+        runthread _ (NextStep v Nothing) =
+                return $ NextStep v Nothing
+
+endThread :: M NextStep
+endThread = nextStep Nothing
+
+background :: M NextStep -> M NextStep
+background job = fork job continue
+
+demo :: M.NextStep
+demo = do
+	showMessage "foo"
+	background $ next $ const $
+		clearMessage >> endThread
+"""]]
+
+That has some warts, but it's good enough for my purposes, and pretty
+awesome for a threading system in 66 LOC.

wip
diff --git a/blog/entry/7drl_2015_day_2_level_generation_and_game_concept.mdwn b/blog/entry/7drl_2015_day_2_level_generation_and_game_concept.mdwn
new file mode 100644
index 0000000..94815f9
--- /dev/null
+++ b/blog/entry/7drl_2015_day_2_level_generation_and_game_concept.mdwn
@@ -0,0 +1,62 @@
+[[!tag haskell 7drl code/scroll]]
+
+Much as I want to get my `@` displayed and moving around screen,
+last night and today have focused on level generation instead.
+
+Scroll has kinda strange level generation method, compared to how
+I suppose most roguelikes do it. There are only 3 calls to `rand`
+in all of Scroll. Just a 3 random parameters, but that's enough to
+ensure a different level each time.
+
+[[!format haskell """
+-- Random level generation function.
+level :: Bool -> StdGen -> [String]
+level randomize r = concat
+        [ final (length tutorial + extra) $ concat $ rand mariner1body
+        , concat $ rand mariner1end
+        , concatMap rand kubla
+        ]
+  where
+	-- here be spoilers
+"""]]
+
+You could say there are two influences in Scroll's level generation method:
+Nick Montfort and Samuel Taylor Coleridge.
+
+----
+
+I have thought some about [[code/Scroll]] before starting the 7drl week,
+but my idea for the game was missing some key concepts. There was nothing
+to keep the player engaged in moving forward, an unclear victory condition,
+no clue how to generate appropriate random levels, a large potential for
+getting stuck, and no way to lose the game. This is all a problem for a
+roguelike. 
+
+But, I had an idea finally last night, about a single unified thing that
+all of that stuff falls out from. And it's right there in the name of the game!
+
+  
+
+Now that I understand Scroll better, I wrote the tutorial level.
+It's a very meta tutorial level that sets the scene well and serves
+more purposes than are at first apparent. I count a total of 6 things
+that this "tutorial level" will let the user do.
+
+And interestingly, while the tutorial level is static, it interacts with the
+rest of the game in a way that will make it be experienced differently
+every time through.
+
+----
+
+The strangest line of code I wrote today is:
+
+	import GPL
+
+Somehow, I have never before, in all my time programming, written a line
+like that one.
+
+----
+
+Finally, after 7 hours of nonstop coding, I got ncurses to display the
+generated game world, scrolling around in the display viewport. No `@`
+yet; that will need to wait for tonight or tomorrow!

Added a comment: `vector` has bounds
diff --git a/blog/entry/7drl_2015_day_1_groundwork/comment_1_2c1e425ccc14bd59f4d191bb26873fa7._comment b/blog/entry/7drl_2015_day_1_groundwork/comment_1_2c1e425ccc14bd59f4d191bb26873fa7._comment
new file mode 100644
index 0000000..4f5f8e5
--- /dev/null
+++ b/blog/entry/7drl_2015_day_1_groundwork/comment_1_2c1e425ccc14bd59f4d191bb26873fa7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="`vector` has bounds"
+ date="2015-03-09T15:54:51Z"
+ content="""
+Hi Joey,
+
+the vectors in the `vector` package keep track of their length and bounds. For unboxed vectors, you might want to look at `Data.Vector.Unboxed.Mutable`.
+"""]]

update
diff --git a/blog/entry/7drl_2015_day_1_groundwork.mdwn b/blog/entry/7drl_2015_day_1_groundwork.mdwn
index 33ef663..38a5dca 100644
--- a/blog/entry/7drl_2015_day_1_groundwork.mdwn
+++ b/blog/entry/7drl_2015_day_1_groundwork.mdwn
@@ -69,7 +69,7 @@ Finally, I wrote some ncurses display code, which is *almost* working.
 
 ----
 
-Hours spent so far: 8
+Start time: After midnight last night. Will end by midnight next Friday.
 
 Lines of code written today: 368
 
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index 1b84c18..8f1564c 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -2,4 +2,4 @@ My entry in the 2015 [7drl](http://7drl.org/) challenge.
 
 Code and online demo coming soon...
 
-[[!inline pages="blog/entry/7drl_2015/*"]]
+[[!inline pages="blog/entry/7drl_2015_*"]]

post
diff --git a/blog/entry/7drl_2015_day_1_groundwork.mdwn b/blog/entry/7drl_2015_day_1_groundwork.mdwn
new file mode 100644
index 0000000..33ef663
--- /dev/null
+++ b/blog/entry/7drl_2015_day_1_groundwork.mdwn
@@ -0,0 +1,91 @@
+[[!tag haskell 7drl code/scroll]]
+
+[[code/Scroll]] is a roguelike, with a twist, which I won't reveal until I've
+finished building it. I'll just say: A playable roguelike pun, set in a
+filesystem near you.
+
+I'm creating Scroll as part of the [7DRL Challange](http://7drl.org/).
+If all goes well, I'll have a usable roguelike game finished in 7 days.
+
+This is my first time developing a roguelike, and my first time writing a
+game in Haskell, and my first time writing a game to a time limit. Wow!
+
+----
+
+First, some groundwork. I'm writing Scroll in Haskell, so let's get the
+core data types and monads and IO squared away. Then I can spend days 2-7
+writing entirely pure functional code, in the Haskell happy place.
+
+To represent the current level, I'm using a Vector of Vectors of Chars.
+Actually, MVectors, which can be mutated safely by pure code running inside
+the ST monad, so it's fast and easy to read or write any particular
+location on the level.
+
+[[!format haskell """
+-- Writes a Char to a position in the world.
+writeWorld :: Pos -> Char -> M ()
+writeWorld (x, y) c = modWorld $ \yv -> do
+	xv <- V.read yv y
+	V.write xv x c
+
+showPlayer :: M ()
+showPlayer = writeWorld (5,8) '@'
+"""]]
+
+(I wish these Vectors had their size as part of their types. There are
+vector libraries on hackage that do, but not the standard vector library,
+which has mutable vectors. As it is, if I try to access outside the bounds
+of the world, it'll crash at runtime.)
+
+Since the game will need some other state, I'm using the state monad. The
+overall monad stack is `type M = StateT S (ST RealWorld)`. (It could be
+`forall s. StateT S (ST s)`, but I had some trouble getting that to type
+check, so I fixed `s` to `RealWorld`, which is ok since it'll be run using
+`stToIO`.
+
+Next, a concept of time, and the main event loop. I decided to use a
+continutation passing style, so the main loop takes 
+the current continuation, and runs it to get a snapshot of the state to
+display, and a new continutation. The advantage of using continuations
+this way is that all the game logic can be handled in the pure code.
+
+I should probably be using the Cont monad in my monad stack, but 
+I've not learned it and lack time. For now I'm handling the
+continuations by hand, which seems ok.
+
+[[!format haskell """
+updateWorld :: Step
+updateWorld (Just 'Q') = do
+        addMessage "Are you sure you want to quit? [yn]"
+        next $ \i -> case i of
+                Just 'y' -> quit
+                _ -> continue
+updateWorld input = do
+        addMessage ("pressed " ++ show input)
+        continue
+"""]]
+
+Finally, I wrote some ncurses display code, which is *almost* working.
+
+----
+
+Hours spent so far: 8
+
+Lines of code written today: 368
+
+Craziest type signature today: `writeS :: forall a. ((Vec2 a -> ST RealWorld ()) -> M ()) -> Pos -> a -> M ()`
+
+----
+
+By the way, there's a whole
+[LambdaHack](http://hackage.haskell.org/package/LambdaHack) library for
+Haskell, targeted at just this kind of roguelike construction. 
+It looks excellent. I'm not using it for two reasons:
+
+1. Scroll is going to be unusual in a lot of ways, and LambdaHack probably
+   makes some assumptions that don't fit.
+2. `mainSer :: (MonadAtomic m, MonadServerReadRequest m) => [String] -> COps -> (m () -> IO ()) -> (COps -> DebugModeCli -> ((FactionId -> ChanServer ResponseUI RequestUI -> IO ()) -> (FactionId -> ChanServer ResponseAI RequestAI -> IO ()) -> IO ()) -> IO ()) -> IO ()`  
+   That's a lot of stuff to figure out! I only have a week, so it's
+   probably easier to build my own framework, and this gives me an
+   opportunity to learn more generally useful stuff, like how to use
+   mutable Vectors.
diff --git a/code.mdwn b/code.mdwn
index a624f5c..52cddd3 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -14,6 +14,7 @@ The stuff that's swapped into my local cache at the moment.
 [[ikiwiki-hosting]]
 [[github-backup]]
 [[shell-monad]]
+[[scroll]]
 
 ## Less active projects
 
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
new file mode 100644
index 0000000..1b84c18
--- /dev/null
+++ b/code/scroll.mdwn
@@ -0,0 +1,5 @@
+My entry in the 2015 [7drl](http://7drl.org/) challenge.
+
+Code and online demo coming soon...
+
+[[!inline pages="blog/entry/7drl_2015/*"]]

cleanup
diff --git a/index.mdwn b/index.mdwn
index 3547430..4cccc7e 100644
--- a/index.mdwn
+++ b/index.mdwn
@@ -28,7 +28,7 @@ input#searchbox {
 .archivepagedate {
 	font-size: 0.5em;
 }
-#actions {
+.actions {
 	display: none;
 }
 </style>

cleanup
diff --git a/index.mdwn b/index.mdwn
index 3b550fa..3547430 100644
--- a/index.mdwn
+++ b/index.mdwn
@@ -28,6 +28,9 @@ input#searchbox {
 .archivepagedate {
 	font-size: 0.5em;
 }
+#actions {
+	display: none;
+}
 </style>
 </div>
 

year
diff --git a/links/interviews.mdwn b/links/interviews.mdwn
index 35dcbfe..f14ba84 100644
--- a/links/interviews.mdwn
+++ b/links/interviews.mdwn
@@ -1,5 +1,5 @@
 ### interviews
 
-[2013: The Setup](http://joey.hess.usesthis.com)  
+[2012: The Setup](http://joey.hess.usesthis.com)  
 [2015: Life after Debian](https://zgrimshell.github.io/interviews-with-floss-developers-joey-hess/)  
 > "I want to build worthwhile things that might last."

interviews
diff --git a/boxen.mdwn b/boxen.mdwn
index 14ab7fd..70be202 100644
--- a/boxen.mdwn
+++ b/boxen.mdwn
@@ -40,7 +40,7 @@ Mostly birds.
 * [[pell]] {*}
 * orca
 * [[clam]] {*}
-* [[diatom]] {*}
+* [[diatom]]
 * [[elephant]] {*}
 
 ## small machines
diff --git a/index.mdwn b/index.mdwn
index fbe185a..3b550fa 100644
--- a/index.mdwn
+++ b/index.mdwn
@@ -39,6 +39,8 @@ input#searchbox {
 </tr>
 </table>
 
+[[!inline feeds=no template=bare pages=links/interviews]]
+
 [[!sidebar content="""
 ### [[blog|blog]] posts
 [[!inline pages="blog/entry/* and !blog/entry/*/* and !link(blog/foo) and !link(unfinished)"
diff --git a/links/interviews.mdwn b/links/interviews.mdwn
new file mode 100644
index 0000000..35dcbfe
--- /dev/null
+++ b/links/interviews.mdwn
@@ -0,0 +1,5 @@
+### interviews
+
+[2013: The Setup](http://joey.hess.usesthis.com)  
+[2015: Life after Debian](https://zgrimshell.github.io/interviews-with-floss-developers-joey-hess/)  
+> "I want to build worthwhile things that might last."

Added a comment: chart error
diff --git a/blog/entry/unicode_eye_chart/comment_2_721ae659831b4eee47c8fd456c01f3f7._comment b/blog/entry/unicode_eye_chart/comment_2_721ae659831b4eee47c8fd456c01f3f7._comment
new file mode 100644
index 0000000..52d3719
--- /dev/null
+++ b/blog/entry/unicode_eye_chart/comment_2_721ae659831b4eee47c8fd456c01f3f7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmQfxu4nNsNvBTKTRcnuCyHRVGUlhZRZ4Y"
+ nickname="Robert"
+ subject="chart error"
+ date="2015-02-08T21:41:39Z"
+ content="""
+Missing descriptor: KANNADA LETTER A
+"""]]

Added a comment
diff --git a/blog/entry/a_bug_in_my_ear/comment_8_4fbfcebf84d149227d883d27eb8e691d._comment b/blog/entry/a_bug_in_my_ear/comment_8_4fbfcebf84d149227d883d27eb8e691d._comment
new file mode 100644
index 0000000..265251e
--- /dev/null
+++ b/blog/entry/a_bug_in_my_ear/comment_8_4fbfcebf84d149227d883d27eb8e691d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl_g6WPKJf26fbRnLq8HUoFNdYdnqr-BZU"
+ nickname="Dale"
+ subject="comment 8"
+ date="2015-02-02T02:23:43Z"
+ content="""
+Another trick is to shine a torch in your ear for a few minutes.  Moth like bugs like to seek out and light and will often find their own way out :)
+"""]]

update blogroll
diff --git a/blog.mdwn b/blog.mdwn
index 86c6f0b..ed4c232 100644
--- a/blog.mdwn
+++ b/blog.mdwn
@@ -26,9 +26,9 @@ Posts per month:
 
 My other blogs:
 
-* [git-annex dev blog](http://git-annex.branchable.com/design/assistant/blog)
+* [git-annex dev blog](https://git-annex.branchable.com/devblog/)
 * [olduse.net blog](http://olduse.net/blog/)
-* [after 1 minute on my modem](http://1-minute-modem.branchable.com)
+* [after 1 minute on my modem](https://1-minute-modem.branchable.com)
 
 Other feeds:
 

comment
diff --git a/blog/entry/dealing_with_dialup/comment_2_4bc8ba277f519f3d04da199bd0a97ecb._comment b/blog/entry/dealing_with_dialup/comment_2_4bc8ba277f519f3d04da199bd0a97ecb._comment
new file mode 100644
index 0000000..a37efeb
--- /dev/null
+++ b/blog/entry/dealing_with_dialup/comment_2_4bc8ba277f519f3d04da199bd0a97ecb._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2015-01-28T16:28:11Z"
+ content="""
+I made that blog post in 2007. What do you think?
+
+... Yeah, of course I'm back on dialup!
+
+See also: 
+
+* [[slow]] (why dialup helps you think)
+* [[roundtrip_latency_from_a_cabin_with_dialup_in_2011]]
+* [after 1 minute on my modem](http://1-minute-modem.branchable.com)
+
+If you feel stuck in a rut or unable to concentrate, go spend a week or a
+month in a cabin with dialup and git and a haskell compiler. It's worked
+great for me.
+"""]]

Added a comment: curious
diff --git a/blog/entry/dealing_with_dialup/comment_1_9a52e2f46fd64302f7ae46e7687e8fb9._comment b/blog/entry/dealing_with_dialup/comment_1_9a52e2f46fd64302f7ae46e7687e8fb9._comment
new file mode 100644
index 0000000..15c7238
--- /dev/null
+++ b/blog/entry/dealing_with_dialup/comment_1_9a52e2f46fd64302f7ae46e7687e8fb9._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="jmz"
+ subject="curious"
+ date="2015-01-28T07:21:20Z"
+ content="""
+Do you still use dial up? I've been meaning to learn a great deal of things but I'm horribly unproductive and find myself torrenting, watching videos, talks, podcasts, tutorials on youtube, etc but never really accomplishing much myself. I find it both amazing and inspiring that you accomplish so much and are so prolific on a dialup connection. Just curious if you've still stuck with dialup all these years later? I might be ditching expensive broadband in favor of something more frugal and trying to develop some self-discipline and a work ethic like yours. Thanks for all the work you've done on Debian and your other projects!
+"""]]

thread
diff --git a/blog/entry/making_propellor_safer_with_GADTs_and_type_families/comment_1_c9c34bfe36d96691bd5a1c8da77aac5c._comment b/blog/entry/making_propellor_safer_with_GADTs_and_type_families/comment_1_c9c34bfe36d96691bd5a1c8da77aac5c._comment
new file mode 100644
index 0000000..7d5ffdd
--- /dev/null
+++ b/blog/entry/making_propellor_safer_with_GADTs_and_type_families/comment_1_c9c34bfe36d96691bd5a1c8da77aac5c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2015-01-25T19:57:30Z"
+ content="""
+The reddit comment thread was very interesting:
+<http://www.reddit.com/r/haskell/comments/2tl8v1/making_propellor_safer_with_gadts_and_type/>
+"""]]

context link
diff --git a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
index 0a61c53..5fedf87 100644
--- a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
+++ b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
@@ -1,4 +1,5 @@
-Since July, I have been aware of an ugly problem with propellor. Certain
+Since July, I have been aware of an ugly problem with 
+[propellor](https://propellor.branchable.com/). Certain
 propellor configurations could have a bug. I've tried to solve the problem at
 least a half-dozen times without success; it's eaten several weekends. 
 

Added a comment: Special remote for Dropbox
diff --git a/blog/entry/case_study:_adding_box.com_support_to_git-annex/comment_4_24d6e3cbc3075f3cd8dd96f2ce5df5b0._comment b/blog/entry/case_study:_adding_box.com_support_to_git-annex/comment_4_24d6e3cbc3075f3cd8dd96f2ce5df5b0._comment
new file mode 100644
index 0000000..ecc54eb
--- /dev/null
+++ b/blog/entry/case_study:_adding_box.com_support_to_git-annex/comment_4_24d6e3cbc3075f3cd8dd96f2ce5df5b0._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmFiUAk6J121dyb5bzx2Ga6STjpn9YPHFk"
+ nickname="Salim"
+ subject="Special remote for Dropbox"
+ date="2015-01-25T13:23:53Z"
+ content="""
+Hi Joey
+A bit late the party, but I'm really enthused about what you've done with git-annex!
+
+I've migrated my main machine to use only open-source software, but am still locked into Dropbox because that's what everyone in my company uses. Since Dropbox insists on installing proprietary software in its client, that's a no-go for me. (My experiments with OwnCloud and a proxy machine runnnig OC and DB failed because Dropbox was too unreliable at handling conflicts, and OC was a CPU hog.)
+
+I bet you've seen https://github.com/TobiasTheViking/dropboxannex by now. (Surprised it wasn't listed in the walkthrough.) I'm about to give it a spin. 
+
+If you're request for a Dropbox account or sponsorship still stands, please let me know.  I think it'd be a great stepping stone for a lot of locked in Dropbox users to be able leave the Dark Side.
+"""]]

format
diff --git a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
index e287ee7..0a61c53 100644
--- a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
+++ b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
@@ -95,7 +95,11 @@ Now I was able to write 4 instances of `Combines`, for each combination
 of 2 Properties with HasInfo or NoInfo.
 
 It type checked. But, type inference was busted. A simple expression
-like <pre>foo `requires` bar</pre> blew up:
+like 
+
+	foo `requires` bar
+
+blew up:
 
 	   No instance for (Requires (Property HasInfo) (Property HasInfo) r0)
 	      arising from a use of `requires'
@@ -106,7 +110,7 @@ like <pre>foo `requires` bar</pre> blew up:
 	                 (Property HasInfo) (Property HasInfo) (Property HasInfo)
 	        -- Defined at Propellor/Types.hs:167:10
 
-To avoid that, it needed <pre>(foo `requires` bar) :: Property HasInfo</pre> --
+To avoid that, it needed ":: Property HasInfo" appended --
 I didn't want the user to need to write that.
 
 I got stuck here for an long time, well over a month.

format
diff --git a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
index 3268552..e287ee7 100644
--- a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
+++ b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
@@ -106,7 +106,7 @@ like <pre>foo `requires` bar</pre> blew up:
 	                 (Property HasInfo) (Property HasInfo) (Property HasInfo)
 	        -- Defined at Propellor/Types.hs:167:10
 
-To avoid that, it needed <pre(foo `requires` bar) :: Property HasInfo</pre> --
+To avoid that, it needed <pre>(foo `requires` bar) :: Property HasInfo</pre> --
 I didn't want the user to need to write that.
 
 I got stuck here for an long time, well over a month.

format
diff --git a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
index 9addbf0..3268552 100644
--- a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
+++ b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
@@ -95,7 +95,7 @@ Now I was able to write 4 instances of `Combines`, for each combination
 of 2 Properties with HasInfo or NoInfo.
 
 It type checked. But, type inference was busted. A simple expression
-like <tt>foo `requires` bar</tt> blew up:
+like <pre>foo `requires` bar</pre> blew up:
 
 	   No instance for (Requires (Property HasInfo) (Property HasInfo) r0)
 	      arising from a use of `requires'
@@ -106,7 +106,7 @@ like <tt>foo `requires` bar</tt> blew up:
 	                 (Property HasInfo) (Property HasInfo) (Property HasInfo)
 	        -- Defined at Propellor/Types.hs:167:10
 
-To avoid that, it needed <tt>(foo `requires` bar) :: Property HasInfo</tt> --
+To avoid that, it needed <pre(foo `requires` bar) :: Property HasInfo</pre> --
 I didn't want the user to need to write that.
 
 I got stuck here for an long time, well over a month.

format
diff --git a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
index 813d5b9..9addbf0 100644
--- a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
+++ b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
@@ -95,7 +95,7 @@ Now I was able to write 4 instances of `Combines`, for each combination
 of 2 Properties with HasInfo or NoInfo.
 
 It type checked. But, type inference was busted. A simple expression
-like `foo \`requires\` bar` blew up:
+like <tt>foo `requires` bar</tt> blew up:
 
 	   No instance for (Requires (Property HasInfo) (Property HasInfo) r0)
 	      arising from a use of `requires'
@@ -106,7 +106,7 @@ like `foo \`requires\` bar` blew up:
 	                 (Property HasInfo) (Property HasInfo) (Property HasInfo)
 	        -- Defined at Propellor/Types.hs:167:10
 
-To avoid that, it needed `(foo \`requires\` bar) :: Property HasInfo` --
+To avoid that, it needed <tt>(foo `requires` bar) :: Property HasInfo</tt> --
 I didn't want the user to need to write that.
 
 I got stuck here for an long time, well over a month.

format
diff --git a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
index ad3ac24..813d5b9 100644
--- a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
+++ b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
@@ -95,7 +95,7 @@ Now I was able to write 4 instances of `Combines`, for each combination
 of 2 Properties with HasInfo or NoInfo.
 
 It type checked. But, type inference was busted. A simple expression
-like "foo `requires` bar" blew up:
+like `foo \`requires\` bar` blew up:
 
 	   No instance for (Requires (Property HasInfo) (Property HasInfo) r0)
 	      arising from a use of `requires'

format
diff --git a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
index 46e59bc..ad3ac24 100644
--- a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
+++ b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
@@ -106,7 +106,7 @@ like "foo `requires` bar" blew up:
 	                 (Property HasInfo) (Property HasInfo) (Property HasInfo)
 	        -- Defined at Propellor/Types.hs:167:10
 
-To avoid that, it needed "(foo `requires` bar) :: Property HasInfo" --
+To avoid that, it needed `(foo \`requires\` bar) :: Property HasInfo` --
 I didn't want the user to need to write that.
 
 I got stuck here for an long time, well over a month.

blog update
diff --git a/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
new file mode 100644
index 0000000..46e59bc
--- /dev/null
+++ b/blog/entry/making_propellor_safer_with_GADTs_and_type_families.mdwn
@@ -0,0 +1,198 @@
+Since July, I have been aware of an ugly problem with propellor. Certain
+propellor configurations could have a bug. I've tried to solve the problem at
+least a half-dozen times without success; it's eaten several weekends. 
+
+Today I finally managed to fix propellor so it's impossible to write code that
+has the bug, bending the Haskell type checker to my will with the power of
+GADTs and type-level functions.
+
+## the bug
+
+Code with the bug looked innocuous enough. Something like this:
+
+[[!format haskell """
+foo :: Property
+foo = property "foo" $
+	unlessM (liftIO $ doesFileExist "/etc/foo") $ do
+		bar <- liftIO $ readFile "/etc/foo.template"
+		ensureProperty $ setupFoo bar
+"""]]
+
+The problem comes about because some properties in propellor have Info
+associated with them. This is used by propellor to introspect over the
+properties of a host, and do things like set up DNS, or decrypt
+private data used by the property.
+
+At the same time, it's useful to let a Property internally decide to
+run some other Property. In the example above, that's the `ensureProperty`
+line, and the `setupFoo` Property is run only sometimes, and is
+passed data that is read from the filesystem.
+
+This makes it very hard, indeed probably impossible for Propellor to
+look inside the monad, realize that `setupFoo` is being used, and add
+its Info to the host.
+
+Probably, `setupFoo` doesn't have Info associated with it -- most
+properties do not. But, it's hard to tell, when writing such a Property
+if it's safe to use ensureProperty. And worse, `setupFoo` could later
+be changed to have Info.
+
+Now, in most languages, once this problem was noticed, the solution would
+probably be to make `ensureProperty` notice when it's called on a Property
+that has Info, and print a warning message. That's Good Enough in a sense.
+
+But it also really stinks as a solution. It means that building propellor
+isn't good enough to know you have a working system; you have to let it
+run on each host, and watch out for warnings. Ugh, no!
+
+## the solution
+
+This screams for GADTs. (Well, it did once I learned how what GADTs are
+and what they can do.) 
+
+With GADTs, `Property NoInfo` and `Property HasInfo` can be separate data
+types. Most functions will work on either type (`Property i`) but
+`ensureProperty` can be limited to only accept a `Property NoInfo`.
+
+[[!format haskell """
+data Property i where
+	IProperty :: Desc -> ... -> Info -> Property HasInfo
+	SProperty :: Desc -> ... -> Property NoInfo
+
+data HasInfo
+data NoInfo
+
+ensureProperty :: Property NoInfo -> Propellor Result
+"""]]
+
+Then the type checker can detect the bug, and refuse to compile it.
+
+Yay!
+
+Except ...
+
+## Property combinators
+
+There are a lot of Property combinators in propellor. These combine
+two or more properties in various ways. The most basic one is `requires`,
+which only runs the first Property after the second one has successfully
+been met.
+
+So, what's it's type when used with GADT Property?
+
+[[!format haskell """
+requires :: Property i1 -> Property i2 -> Property ???
+"""]]
+
+It seemed I needed some kind of type class, to vary the return type.
+
+[[!format haskell """
+class Combine x y r where
+	requires :: x -> y -> r
+"""]]
+
+Now I was able to write 4 instances of `Combines`, for each combination
+of 2 Properties with HasInfo or NoInfo.
+
+It type checked. But, type inference was busted. A simple expression
+like "foo `requires` bar" blew up:
+
+	   No instance for (Requires (Property HasInfo) (Property HasInfo) r0)
+	      arising from a use of `requires'
+	    The type variable `r0' is ambiguous
+	    Possible fix: add a type signature that fixes these type variable(s)
+	    Note: there is a potential instance available:
+	      instance Requires
+	                 (Property HasInfo) (Property HasInfo) (Property HasInfo)
+	        -- Defined at Propellor/Types.hs:167:10
+
+To avoid that, it needed "(foo `requires` bar) :: Property HasInfo" --
+I didn't want the user to need to write that.
+
+I got stuck here for an long time, well over a month.
+
+## type level programming
+
+Finally today I realized that I could fix this with a little type-level
+programming.
+
+[[!format haskell """
+class Combine x y where
+	requires :: x -> y -> CombinedType x y
+"""]]
+
+Here `CombinedType` is a type-level function, that calculates the type that
+should be used for a combination of types x and y. This turns out to be really
+easy to do, once you get your head around type level functions.
+
+[[!format haskell """
+type family CInfo x y
+type instance CInfo HasInfo HasInfo = HasInfo
+type instance CInfo HasInfo NoInfo = HasInfo
+type instance CInfo NoInfo HasInfo = HasInfo
+type instance CInfo NoInfo NoInfo = NoInfo
+type family CombinedType x y
+type instance CombinedType (Property x) (Property y) = Property (CInfo x y)
+"""]]
+
+And, with that change, type inference worked again! \o/
+
+(Bonus: I added some more intances of CombinedType for combining
+things like RevertableProperties, so propellor's property
+combinators got more powerful too.)
+
+Then I just had to make a massive pass over all of Propellor,
+fixing the types of each Property to be Property NoInfo or Property HasInfo.
+I frequently picked the wrong one, but the type checker was able to detect 
+and tell me when I did.
+
+A few of the type signatures got slightly complicated, to provide the type
+checker with sufficient proof to do its thing...
+
+[[!format haskell """
+before :: (IsProp x, Combines y x, IsProp (CombinedType y x)) => x -> y -> CombinedType y x
+before x y = (y `requires` x) `describe` (propertyDesc x)
+
+onChange
+	:: (Combines (Property x) (Property y))
+	=> Property x
+	=> Property y
+	=> CombinedType (Property x) (Property y)
+onChange = -- 6 lines of code omitted
+
+fallback :: (Combines (Property p1) (Property p2)) => Property p1 -> Property p2 -> Property (CInfo p1 p2)
+fallback = -- 4 lines of code omitted
+"""]]
+
+.. This mostly happened in property combinators, which is an acceptable
+tradeoff, when you consider that the type checker is now being used to prove
+that propellor can't have this bug.
+
+Mostly, things went just fine. The only other annoying thing was that some
+things use a `[Property]`, and since a haskell list can only contain a
+single type, while Property Info and Property NoInfo are two different
+types, that needed to be dealt with. Happily, I was able to extend
+propellor's existing `(&)` and `(!)` operators to work in this situation,
+so a list can be constructed of properties of several different types:
+
+[[!format haskell """
+propertyList "foos" $ props
+	& foo
+	& foobar
+	! oldfoo	
+"""]]
+
+## conclusion
+
+The resulting 4000 lines of changes will be in the next release of
+propellor. Just as soon as I test that it always generates the same Info
+as before, and perhaps works when I run it. (eep)
+
+These uses of GADTs and type families are not new; this is merely the first
+time I used them. It's another Haskell leveling up for me. 
+
+Anytime you can identify a class of bugs that can impact a complicated code

(Diff truncated)
add news item for moreutils 0.55
diff --git a/code/moreutils/news/version_0.49.mdwn b/code/moreutils/news/version_0.49.mdwn
deleted file mode 100644
index e507d68..0000000
--- a/code/moreutils/news/version_0.49.mdwn
+++ /dev/null
@@ -1,6 +0,0 @@
-moreutils 0.49 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * ts: Fix timezone used with -i
-   * errno, isutf8: Fix zero-termination of option list, which could lead
-     to getopt crash. Closes: #[715867](http://bugs.debian.org/715867)
-     (Thanks, Mayhem Team)"""]]
\ No newline at end of file
diff --git a/code/moreutils/news/version_0.55.mdwn b/code/moreutils/news/version_0.55.mdwn
new file mode 100644
index 0000000..dfe7d60
--- /dev/null
+++ b/code/moreutils/news/version_0.55.mdwn
@@ -0,0 +1,6 @@
+moreutils 0.55 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * parallel: serialise output through internal pipe. Closes: #[704125](http://bugs.debian.org/704125)
+     Thanks, Nicolas Schier.
+   * sponge: add append option '-a'. Closes: #[623197](http://bugs.debian.org/623197)
+     Thanks, Nicolas Schier."""]]
\ No newline at end of file

correction
diff --git a/code/bin.mdwn b/code/bin.mdwn
index 31b7669..a4ff3e5 100644
--- a/code/bin.mdwn
+++ b/code/bin.mdwn
@@ -42,7 +42,7 @@ This is the script that I use for releasing packages.
 ## wikiannounce
 
 This is a script that release calls, which converts a changelog into
-a news item for a package on this wiki.
+a news item for a package on its wiki.
 
 ## foto
 

more
diff --git a/code/bin.mdwn b/code/bin.mdwn
index cdd6dab..31b7669 100644
--- a/code/bin.mdwn
+++ b/code/bin.mdwn
@@ -12,6 +12,12 @@ there still.
 
 You can browse my bin at <http://git.kitenet.net/?p=joey/home.git;a=tree;f=bin>.
 
+## async
+
+Passed a mount point and a command, it remounts the drive at that point
+async, runs the command, and then remounts it back sync. Useful with
+external drives that are mounted sync by default for safety.
+
 ## blog
 
 This brings up a text editor for writing a
@@ -38,12 +44,10 @@ This is the script that I use for releasing packages.
 This is a script that release calls, which converts a changelog into
 a news item for a package on this wiki.
 
-## dq
-
-This is my Download Queue program. Uses rsync to synchronise files, very
-handy if you're on a slow modem link.
+## foto
 
-(Now obsoleted by [[code/git-annex]])
+Pulls photos off a camera. Either from a DCIM directory of a mounted SD
+card, or using gphoto2 over USB. The photos are added to a git-annex repo.
 
 ## loadcron
 
@@ -55,6 +59,11 @@ Supports some handy features.
 Given a list of architectures on command line or stdin, 
 outputs any of the released debian arches not in the list
 
+## lifeday
+
+Prints out the number of days since I was born. Useful for a different
+perspective.
+
 ## logview
 
 What I use for tailing logfiles. Determines dynamically what files are
@@ -67,11 +76,20 @@ which sucks on 3 line xterms).
 Sshs into a machine and starts a screen session. Auto-reconnects.
 Goto considered wonderful!
 
-## scancd
+## out
 
-I keep a file that records all the files on archival CDs that I burn; this
-updates the file. Uses vim folding markers to make it easy to browse the
-file in vim; the file is also always stored compressed. (It's big.)
+For use in a git-annex repository containing files that are being consumed
+in some way (eg, videos or podcasts), where I want to keep a copy of the
+file but get it out of the way when done with it. Moves specified files to
+some "out" directory located inside the repository, and has git-annex drop
+their content if possible.
+
+## rec
+
+Simple sound recorder. Streams the mic to a fifo and in the background,
+encodes it to an ogg file. This can be easily started up, and runs until
+ctrl-C'd. Then the finished ogg file is stashed away in a git-annex
+repository.
 
 ## sunrise
 
@@ -85,3 +103,10 @@ It does have to have LAT/LONG hardcoded into it though.
 This makes su actually run the the sudo command, if sudo is present. Nice
 to not have to type the password every time when suing, although I wrote it
 before I was aware of "`sudo su`".
+
+## z
+
+Blocks suspend on lid close while a command runs. Useful for eg, listening
+to a podcast, or keeping the laptop running until a download completes.
+
+Requires some systemd setup documented in comments.

update
diff --git a/code/bin.mdwn b/code/bin.mdwn
index ab0f31f..cdd6dab 100644
--- a/code/bin.mdwn
+++ b/code/bin.mdwn
@@ -22,20 +22,20 @@ with pyblosxom instead.
 
 ## build
 
-This is the script that I use for building Debian packages.
+This is the script that I use for building packages.
 
 ## review
 
-This is the script I use for running lintian and other checks on a Debian
+This is the script I use for running lintian and other checks on a
 package I've built. It displays all sorts of useful info in a pager.
 
 ## release
 
-This is the script that I use for releasing Debian packages.
+This is the script that I use for releasing packages.
 
 ## wikiannounce
 
-This is a script that release calls, which converts a debian changelog into
+This is a script that release calls, which converts a changelog into
 a news item for a package on this wiki.
 
 ## dq

reorg
diff --git a/code.mdwn b/code.mdwn
index 1701230..a624f5c 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -28,35 +28,42 @@ In maintenance mode mostly, but I still have my hands in it somewhat.
 
 ## Past projects
 
-I'm no longer working on these projects.
+I'm no longer working on these projects, but thankfully, other
+people have taken them on.
 
 [[Debian]]
 [[debian-installer]]
 [[debhelper]]
 [[tasksel]]
-[[debmirror]]
-[[shoop]]
-[[apt-src]]
-[[pentium-builder]]
-[[perlmoo]]
-[[TermStool]]
-[[base-config]]
 [[flashybrid]]
-[[satutils]]
-[[mooix]]
 [[wmbattery]]
-[[sleepd]]
-[[pristine-tar]]
-[[alien]]
 [[debconf]]
 [[dpkg-repack]]
 [[os-prober]]
 [[devscripts]]
+[[pentium-builder]]
+[[apt-src]]
+
+These need new maintainers, stat!
+
+[[debmirror]]
+[[sleepd]]
+[[pristine-tar]]
+[[alien]]
 [[jetring]]
 [[nslu2-utils]]
-[[rootsync]]
 [[ticker]]
 
+These are dead and buried.
+
+[[shoop]]
+[[perlmoo]]
+[[TermStool]]
+[[base-config]]
+[[satutils]]
+[[mooix]]
+[[rootsync]]
+
 ## Misc
 
 Other stuff..
diff --git a/code/debian-installer.mdwn b/code/debian-installer.mdwn
index 5573352..dcf0905 100644
--- a/code/debian-installer.mdwn
+++ b/code/debian-installer.mdwn
@@ -8,5 +8,5 @@ Its website is formally <http://www.debian.org/devel/debian-installer>, but
 <http://wiki.debian.org/DebianInstaller> is perhaps more interesting.
 
 The [[dilab]] was my own rack of d-i test
-machines. This runs on `digress`, the d-i regression suite, which is the
+machines. This ran on `digress`, the d-i regression suite, which is the
 most obscure part of d-i I know of, and which I wrote.

update re oprhanings and etc
diff --git a/code.mdwn b/code.mdwn
index a331b58..1701230 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -28,12 +28,7 @@ In maintenance mode mostly, but I still have my hands in it somewhat.
 
 ## Past projects
 
-Still theoretically maintained by me, but new maintainers needed for
-continued life:
-
-[[ticker]]
-
-Passed on to others, or dead and buried:
+I'm no longer working on these projects.
 
 [[Debian]]
 [[debian-installer]]
@@ -60,6 +55,7 @@ Passed on to others, or dead and buried:
 [[jetring]]
 [[nslu2-utils]]
 [[rootsync]]
+[[ticker]]
 
 ## Misc
 
diff --git a/code/debhelper.mdwn b/code/debhelper.mdwn
index 75feb55..b0dabf3 100644
--- a/code/debhelper.mdwn
+++ b/code/debhelper.mdwn
@@ -29,9 +29,7 @@ maintaining support for said obscure thing.
 
 My first rule of thumb is that at least ten packages need to be obvious
 benefactors of a feature or command before it's added to debhelper. That's
-an easy bar; after that I have to do some thinking and made the hard call.
-
-TODO: discuss wishlisted commands here
+an easy bar; after that I have to do some thinking and make the hard call.
 
 [[!sidebar content="""
 <a href="http://flattr.com/thing/39941/Debhelper" target="_blank">
diff --git a/code/debhelper/news/no_longer_maintaining_debhelper.mdwn b/code/debhelper/news/no_longer_maintaining_debhelper.mdwn
new file mode 100644
index 0000000..46ba21b
--- /dev/null
+++ b/code/debhelper/news/no_longer_maintaining_debhelper.mdwn
@@ -0,0 +1,2 @@
+I've passed maintanence for debhelper on to others. This page is provided
+only for historical reasons.

orphaned ailen
diff --git a/code/alien/news/no_longer_maintaining_alien.mdwn b/code/alien/news/no_longer_maintaining_alien.mdwn
new file mode 100644
index 0000000..692aa0d
--- /dev/null
+++ b/code/alien/news/no_longer_maintaining_alien.mdwn
@@ -0,0 +1 @@
+I am no longer maintaining alien. A new maintainer is wanted.

mooix archive link etc
diff --git a/code/mooix.mdwn b/code/mooix.mdwn
index ede096d..1375e85 100644
--- a/code/mooix.mdwn
+++ b/code/mooix.mdwn
@@ -1,9 +1,13 @@
 Mooix is a MOO that is implemented on top of unix and which can be
-programmed online in any language. Its website is <http://mooix.net/>.
+programmed online in any language.
 
-I'm not currently using or developing mooix; a few other people make
-commits from time to time. I have some [[grandiose_plans|ng]] for the next
-generation of mooix, which I might get around to fleshing out some day.
+I stopped developing mooix around 2001; a few other people made
+commits from time to time for the next decade, but now it is done.
+
+I have some [[grandiose_plans|ng]] for the next generation of mooix,
+which I might get around to fleshing out some day, but probably not.
 
 Some thoughts on mooix in my
 [[blog|blog/entry/ten_years_of_free_software_--_part_17_mooix]].
+
+Mooix is archived: <https://archive.org/details/MooixArchive>

Added a comment: bug in my ear
diff --git a/blog/entry/a_bug_in_my_ear/comment_7_a4ea38bfa03050cfb39bb084a247eb85._comment b/blog/entry/a_bug_in_my_ear/comment_7_a4ea38bfa03050cfb39bb084a247eb85._comment
new file mode 100644
index 0000000..860ae44
--- /dev/null
+++ b/blog/entry/a_bug_in_my_ear/comment_7_a4ea38bfa03050cfb39bb084a247eb85._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkjqspuRFhqOXA8hoESjDm0I45gYL9v9Lk"
+ nickname="Peter"
+ subject="bug in my ear"
+ date="2015-01-06T10:31:28Z"
+ content="""
+Never EVER use a cotton bud!
+1. Your parents probably taught you that and it's really bad.
+2. Cotton buds generally fill the ear canal and then like loading a cannon (That's apt?) push all that crap further down your ear like a ram rod.
+
+Some people use hair grips a bit like a scraper but you need to be dead careful not to damage the ear drum. Best option warm olive oil and pour that in your lughole (Urban Dictionary) after a couple of minutes drain it out. The warmer the better to melt any minging ear wax. :-)
+"""]]

Added a comment: RC?
diff --git a/blog/entry/a_bug_in_my_ear/comment_6_2c4011193d9dd2497ba6aea159bb237c._comment b/blog/entry/a_bug_in_my_ear/comment_6_2c4011193d9dd2497ba6aea159bb237c._comment
new file mode 100644
index 0000000..2d70802
--- /dev/null
+++ b/blog/entry/a_bug_in_my_ear/comment_6_2c4011193d9dd2497ba6aea159bb237c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="RC?"
+ date="2015-01-06T10:00:52Z"
+ content="""
+So you are saying that while this bug was not critical for the release, the release of this bug was critical for you?
+"""]]

tag
diff --git a/blog/entry/hledger.mdwn b/blog/entry/hledger.mdwn
index 85d8ae3..324f48c 100644
--- a/blog/entry/hledger.mdwn
+++ b/blog/entry/hledger.mdwn
@@ -221,3 +221,5 @@ Of course, a Haskell programmer can skip the monads entirely, or use others
 they prefer. And could do arbitrarily complicated stuff during imports,
 including building split transactions, and combining together multiple
 related CVS lines into a single transaction.
+
+[[!tag haskell]]

foo
diff --git a/blog/entry/a_bug_in_my_ear/comment_5_e62e8977fc1f67c4d44654b483c30adb._comment b/blog/entry/a_bug_in_my_ear/comment_5_e62e8977fc1f67c4d44654b483c30adb._comment
new file mode 100644
index 0000000..66de52e
--- /dev/null
+++ b/blog/entry/a_bug_in_my_ear/comment_5_e62e8977fc1f67c4d44654b483c30adb._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 5"""
+ date="2015-01-06T05:29:38Z"
+ content="""
+I loled at the bug report comment!
+
+JFTR, the cue-tips I used are the big-ended safe kind that intentionally cannot
+be jammed all the way down the canal to the eardrum.
+
+A few years ago, I had a strange earache, that came on without any swimming
+or other activity that might lead to an ear infection. Now I'm wondering if
+that one was also caused by some little bug, perhaps while I was asleep.
+
+Ear canals.. what was evolution thinking?
+"""]]

Added a comment
diff --git a/blog/entry/a_bug_in_my_ear/comment_4_b7d72d7147ddb255492007389e09f1da._comment b/blog/entry/a_bug_in_my_ear/comment_4_b7d72d7147ddb255492007389e09f1da._comment
new file mode 100644
index 0000000..80af23a
--- /dev/null
+++ b/blog/entry/a_bug_in_my_ear/comment_4_b7d72d7147ddb255492007389e09f1da._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawndhZ128v4P20FCgptVRqrP0bOwPpi2EQA"
+ nickname="Patrick"
+ subject="comment 4"
+ date="2015-01-06T03:20:08Z"
+ content="""
+Happened to me when I was around 10 years old.  I remember thinking it was going to flap in there forever.
+"""]]

Added a comment
diff --git a/blog/entry/a_bug_in_my_ear/comment_3_fa24ff02463a7396ef768cdff7e5d04c._comment b/blog/entry/a_bug_in_my_ear/comment_3_fa24ff02463a7396ef768cdff7e5d04c._comment
new file mode 100644
index 0000000..e7d9dd6
--- /dev/null
+++ b/blog/entry/a_bug_in_my_ear/comment_3_fa24ff02463a7396ef768cdff7e5d04c._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlYPDgJVIC9eiG2E7I480vFHmmWXn0Nauc"
+ nickname="Piruthiviraj"
+ subject="comment 3"
+ date="2015-01-06T03:05:15Z"
+ content="""
+People, never try earbuds to remove the living foreign body from the ear. First stop panicking! Rest the head on a bed and always use fluids eg. lukewarm water to fill the ear canal and usually after few mins, bugs usually comes out or at least dies and helps in easier extraction at the hospital.
+If you have been diagnosed to have previous ear infection or a persistant ear perforation, always seek medical help, before manipulating yourself.
+The more the manipulation the more likely the bug or the earbud is going to injure the cavity and later leading a ear infection.
+I am an ER Physcian and hence you can depend on the info.
+"""]]

Added a comment
diff --git a/blog/entry/a_bug_in_my_ear/comment_2_0f4d749540e955b707a07f57284db9ca._comment b/blog/entry/a_bug_in_my_ear/comment_2_0f4d749540e955b707a07f57284db9ca._comment
new file mode 100644
index 0000000..44039f1
--- /dev/null
+++ b/blog/entry/a_bug_in_my_ear/comment_2_0f4d749540e955b707a07f57284db9ca._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn8AYPzWP-WL-z-EOr_EBp7Kd44DxEYNxE"
+ nickname="Benjamin"
+ subject="comment 2"
+ date="2015-01-06T02:23:54Z"
+ content="""
+The exact same thing happened to my girlfriend about 10 years ago. She treated it with ear-drops just like you did, and she doesn't suffer any drawback except from being afraid by those kind of bugs. So my guess is that you should be alright too :-)
+"""]]

removed
diff --git a/blog/entry/a_bug_in_my_ear/comment_2_5872742ed8e7cce48993cbbfb923d7f4._comment b/blog/entry/a_bug_in_my_ear/comment_2_5872742ed8e7cce48993cbbfb923d7f4._comment
deleted file mode 100644
index ca03ca7..0000000
--- a/blog/entry/a_bug_in_my_ear/comment_2_5872742ed8e7cce48993cbbfb923d7f4._comment
+++ /dev/null
@@ -1,7 +0,0 @@
-[[!comment format=mdwn
- username="http://bret.io/"
- subject="comment 2"
- date="2015-01-06T01:58:58Z"
- content="""
-Thanks for your bug report.  ;)
-"""]]

Added a comment
diff --git a/blog/entry/a_bug_in_my_ear/comment_2_5872742ed8e7cce48993cbbfb923d7f4._comment b/blog/entry/a_bug_in_my_ear/comment_2_5872742ed8e7cce48993cbbfb923d7f4._comment
new file mode 100644
index 0000000..ca03ca7
--- /dev/null
+++ b/blog/entry/a_bug_in_my_ear/comment_2_5872742ed8e7cce48993cbbfb923d7f4._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://bret.io/"
+ subject="comment 2"
+ date="2015-01-06T01:58:58Z"
+ content="""
+Thanks for your bug report.  ;)
+"""]]

Added a comment
diff --git a/blog/entry/a_bug_in_my_ear/comment_1_51853f770fe2e217878b582dbab3e701._comment b/blog/entry/a_bug_in_my_ear/comment_1_51853f770fe2e217878b582dbab3e701._comment
new file mode 100644
index 0000000..d205f08
--- /dev/null
+++ b/blog/entry/a_bug_in_my_ear/comment_1_51853f770fe2e217878b582dbab3e701._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://bret.io/"
+ subject="comment 1"
+ date="2015-01-06T01:58:50Z"
+ content="""
+Thanks for your bug report.  ;)
+"""]]

blog update
diff --git a/blog/entry/a_bug_in_my_ear.mdwn b/blog/entry/a_bug_in_my_ear.mdwn
new file mode 100644
index 0000000..1b6e171
--- /dev/null
+++ b/blog/entry/a_bug_in_my_ear.mdwn
@@ -0,0 +1,18 @@
+True story: Two days ago, as I was about to drift off to sleep at 2 am, a tiny
+little bug flew into my ear. Right down to my eardrum, which it fluttered
+against with its wings.
+
+It was a tiny little moth-like bug, the kind you don't want to find in a bag of
+flour, and it had been beating against my laptop screen a few minutes before.
+
+This went on for 20 minutes, in which I failed to get it out with a cue tip and
+shaking my head. It is very weird to have a bug flapping in your head.
+
+I finally gave up and put in eardrops, and stopped the poor thing flapping. I
+happen to know these little creatures mass almost nothing, and rapidly break up
+into nearly powder when dead. So while I've not had any bug bits come out, I'm
+going by the way my ear felt a little stopped up yesterday, and just fine
+today, and guessing it'll be ok. Oh, and I've been soaking it in the tub and
+putting in eardrops for good measure.
+
+If I've seemed a little distracted lately, now you know why!

calendar update
diff --git a/blog/archives/2015.mdwn b/blog/archives/2015.mdwn
new file mode 100644
index 0000000..801aa04
--- /dev/null
+++ b/blog/archives/2015.mdwn
@@ -0,0 +1 @@
+[[!calendar type=year year=2015 pages="blog/entry/* and !*/Discussion"]]
diff --git a/blog/archives/2015/01.mdwn b/blog/archives/2015/01.mdwn
new file mode 100644
index 0000000..55e62f8
--- /dev/null
+++ b/blog/archives/2015/01.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=01 year=2015 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(01) and creation_year(2015) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2015/02.mdwn b/blog/archives/2015/02.mdwn
new file mode 100644
index 0000000..47ca1c8
--- /dev/null
+++ b/blog/archives/2015/02.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=02 year=2015 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(02) and creation_year(2015) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2015/03.mdwn b/blog/archives/2015/03.mdwn
new file mode 100644
index 0000000..6e9a783
--- /dev/null
+++ b/blog/archives/2015/03.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=03 year=2015 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(03) and creation_year(2015) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2015/04.mdwn b/blog/archives/2015/04.mdwn
new file mode 100644
index 0000000..05a8508
--- /dev/null
+++ b/blog/archives/2015/04.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=04 year=2015 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(04) and creation_year(2015) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2015/05.mdwn b/blog/archives/2015/05.mdwn
new file mode 100644
index 0000000..775c0e1
--- /dev/null
+++ b/blog/archives/2015/05.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=05 year=2015 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(05) and creation_year(2015) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2015/06.mdwn b/blog/archives/2015/06.mdwn
new file mode 100644
index 0000000..5bea3ab
--- /dev/null
+++ b/blog/archives/2015/06.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=06 year=2015 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(06) and creation_year(2015) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2015/07.mdwn b/blog/archives/2015/07.mdwn
new file mode 100644
index 0000000..6e1a33f
--- /dev/null
+++ b/blog/archives/2015/07.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=07 year=2015 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(07) and creation_year(2015) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2015/08.mdwn b/blog/archives/2015/08.mdwn
new file mode 100644
index 0000000..cfafb75
--- /dev/null
+++ b/blog/archives/2015/08.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=08 year=2015 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(08) and creation_year(2015) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2015/09.mdwn b/blog/archives/2015/09.mdwn
new file mode 100644
index 0000000..68e4d24
--- /dev/null
+++ b/blog/archives/2015/09.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=09 year=2015 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(09) and creation_year(2015) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2015/10.mdwn b/blog/archives/2015/10.mdwn
new file mode 100644
index 0000000..01c1f46
--- /dev/null
+++ b/blog/archives/2015/10.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=10 year=2015 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(10) and creation_year(2015) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2015/11.mdwn b/blog/archives/2015/11.mdwn
new file mode 100644
index 0000000..3f5f6e2
--- /dev/null
+++ b/blog/archives/2015/11.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=11 year=2015 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(11) and creation_year(2015) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/blog/archives/2015/12.mdwn b/blog/archives/2015/12.mdwn
new file mode 100644
index 0000000..6ca3ef0
--- /dev/null
+++ b/blog/archives/2015/12.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=12 year=2015 pages="blog/entry/* and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(12) and creation_year(2015) and blog/entry/* and !*/Discussion" show=0 feeds=no reverse=yes]]

update with gpg key
not currently using jabber
diff --git a/contact.mdwn b/contact.mdwn
index 79d9fee..1d7d141 100644
--- a/contact.mdwn
+++ b/contact.mdwn
@@ -1,4 +1,4 @@
-* email: <id@joeyh.name> or <joey@kitenet.net> or <joeyh@debian.org>
-* jabber: [joey@kitenet.net](xmpp:joey@kitenet.net)
+* email: <id@joeyh.name>
+* gpg key: [E85A 5F63 B31D 24C1 EBF0  D81C C910 D922 2512 E3C7](http://pgp.cs.uu.nl/stats/2512E3C7.html)
 * identi.ca: <http://identi.ca/joeyh>
 * some ways to send me a "thank you" for my work, if you're so inclined: [[thanks]]