Recent changes to this wiki:

Add clarification to links page
diff --git a/links.mdwn b/links.mdwn
index 5cda482..347bdc5 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -8,6 +8,9 @@ browser was inconvenient. Also, browser bookmark support sucked. So
 instead I started keeping a web page with links. This is the current
 incarnation of that web page.
 
+Just to be clear: don't suggest links for me to add. I delete such
+suggestions reflexively.
+
 **Frequent:**
 [Valuutat](http://www.suomenpankki.fi/en/tilastot/valuuttakurssit/Pages/tilastot_valuuttakurssit_valuuttakurssit_today_en.aspx)
 [Sanakirja](http://www.sanakirja.org/)

Add a clarifiction about timers
diff --git a/ick/tiny.txt b/ick/tiny.txt
index eba1c63..27e7612 100644
--- a/ick/tiny.txt
+++ b/ick/tiny.txt
@@ -49,6 +49,9 @@ source:
 # Each trigger is implemented by excuting a shell snippet, capturing and
 # storing its output. The trigger fires when the output is different
 # from the stored value.
+#
+# For the timer trigger, we assume a process outside the controller that
+# calls the trigger api every so often. (This isn't very pretty.)
 triggers:
   source_change:
     get_value: |

Rename to .txt
diff --git a/ick/tiny.txt b/ick/tiny.txt
new file mode 100644
index 0000000..eba1c63
--- /dev/null
+++ b/ick/tiny.txt
@@ -0,0 +1,98 @@
+# This is meant to be self-contained ick file for ick2, for a minimal
+# tiny project: that of building a website with ikiwiki from git.
+
+# We need a single worker. All pipeline steps are run on this worker,
+# over ssh. If we had more workers, and enough steps, the controller
+# would choose which one would run each step.
+workers:
+  localhost:
+    user: null
+    address: localhost
+    protocol: ssh
+
+# We likewise have a single project.
+projects:
+  obnam_www:
+    source:
+      subdir: .
+      type: git
+      url: ssh://git@git.liw.fi/obnam-www
+      branch: master
+    pipelines:
+      - name: build_and_publish_ikiwiki
+        triggered_by:
+          - source_change
+          - name: timer
+            interval: 1d
+        parameters:
+          rsync_dest: liw@pieni.net:/srv/www.obnam.org
+
+# We define here how source is retrieved for various version control
+# systems. The controller will run the get_all or update command to
+# freshen its copy of the source, and after it's done that, it checks
+# if pipelines get triggered. The freshening is done when it seems
+# like a trigger might be about to fire. Some env vars are defined by
+# the controller when running the shell snippets.
+source:
+  git:
+    get_all: |
+      git clone -b "$BRANCH" "$URL" "$SRCDIR"
+    update: |
+      cd "$SRCDIR" && git pull
+
+# Triggers define when a pipeline needds to run. Triggers are evaluated
+# whenever the source has been updated, or when there is external
+# stimuli, via an HTTP request to the controller
+# (http://controller/trigger/obnam_www/source_changed, which causes the
+# controller to freshen the source, and then evaluate the foo trigger).
+#
+# Each trigger is implemented by excuting a shell snippet, capturing and
+# storing its output. The trigger fires when the output is different
+# from the stored value.
+triggers:
+  source_change:
+    get_value: |
+      git show --pretty=oneline HEAD | head -n1
+  timer:
+    get_value: |
+      now="$(date +%s)
+      interval="$(get_parameter interval)"
+      next="$(echo "$STORED_VALUE" + "$interval")
+      if [ "$next" -lt "$now" ]
+      then
+          echo "$STORED_VALUE"
+      else
+          echo "$next"
+      fi
+
+# A pipeline is a list of steps to execute. It declares some
+# parameters that must be defined by the project. These are inherited
+# by each step. Also, the pipline may define variables whose values
+# get given to steps as parameters.
+pipelines:
+  build_and_publish_ikiwiki:
+    parameters:
+      - rsync_dest
+    variables:
+      htmldir: tmp.html
+    steps:
+      - run_ikiwiki
+      - run_rsync
+
+pipeline_steps:
+  run_ikiwiki:
+    parameters:
+      - htmldir
+    shell: |
+      tmp=tmp.setup
+      cat ikiwiki.setup > "$tmp"
+      echo "  srcdir: $(pwd)" >> "$tmp"
+      echo "  destdir: {{ htmldir }}" >> "$tmp"
+      rm -rf "{{ htmldir }}"
+      ikiwiki --setup "$tmp" --gettime --rebuild
+  run_rsync:
+    parameters:
+      - htmldir
+      - rsync_dest
+    shell: |
+      rsync -ahHSPs --delete "{{ htmldir }}/." "{{ rsync_dest }}/."
diff --git a/ick/tiny.yaml b/ick/tiny.yaml
deleted file mode 100644
index eba1c63..0000000
--- a/ick/tiny.yaml
+++ /dev/null
@@ -1,98 +0,0 @@
-# This is meant to be self-contained ick file for ick2, for a minimal
-# tiny project: that of building a website with ikiwiki from git.
-
-# We need a single worker. All pipeline steps are run on this worker,
-# over ssh. If we had more workers, and enough steps, the controller
-# would choose which one would run each step.
-workers:
-  localhost:
-    user: null
-    address: localhost
-    protocol: ssh
-
-# We likewise have a single project.
-projects:
-  obnam_www:
-    source:
-      subdir: .
-      type: git
-      url: ssh://git@git.liw.fi/obnam-www
-      branch: master
-    pipelines:
-      - name: build_and_publish_ikiwiki
-        triggered_by:
-          - source_change
-          - name: timer
-            interval: 1d
-        parameters:
-          rsync_dest: liw@pieni.net:/srv/www.obnam.org
-
-# We define here how source is retrieved for various version control
-# systems. The controller will run the get_all or update command to
-# freshen its copy of the source, and after it's done that, it checks
-# if pipelines get triggered. The freshening is done when it seems
-# like a trigger might be about to fire. Some env vars are defined by
-# the controller when running the shell snippets.
-source:
-  git:
-    get_all: |
-      git clone -b "$BRANCH" "$URL" "$SRCDIR"
-    update: |
-      cd "$SRCDIR" && git pull
-
-# Triggers define when a pipeline needds to run. Triggers are evaluated
-# whenever the source has been updated, or when there is external
-# stimuli, via an HTTP request to the controller
-# (http://controller/trigger/obnam_www/source_changed, which causes the
-# controller to freshen the source, and then evaluate the foo trigger).
-#
-# Each trigger is implemented by excuting a shell snippet, capturing and
-# storing its output. The trigger fires when the output is different
-# from the stored value.
-triggers:
-  source_change:
-    get_value: |
-      git show --pretty=oneline HEAD | head -n1
-  timer:
-    get_value: |
-      now="$(date +%s)
-      interval="$(get_parameter interval)"
-      next="$(echo "$STORED_VALUE" + "$interval")
-      if [ "$next" -lt "$now" ]
-      then
-          echo "$STORED_VALUE"
-      else
-          echo "$next"
-      fi
-
-# A pipeline is a list of steps to execute. It declares some
-# parameters that must be defined by the project. These are inherited
-# by each step. Also, the pipline may define variables whose values
-# get given to steps as parameters.
-pipelines:
-  build_and_publish_ikiwiki:
-    parameters:
-      - rsync_dest
-    variables:
-      htmldir: tmp.html
-    steps:
-      - run_ikiwiki
-      - run_rsync
-
-pipeline_steps:
-  run_ikiwiki:
-    parameters:
-      - htmldir
-    shell: |
-      tmp=tmp.setup
-      cat ikiwiki.setup > "$tmp"
-      echo "  srcdir: $(pwd)" >> "$tmp"
-      echo "  destdir: {{ htmldir }}" >> "$tmp"

(Diff truncated)
Add a tiny ick2 example
diff --git a/ick/tiny.yaml b/ick/tiny.yaml
new file mode 100644
index 0000000..eba1c63
--- /dev/null
+++ b/ick/tiny.yaml
@@ -0,0 +1,98 @@
+# This is meant to be self-contained ick file for ick2, for a minimal
+# tiny project: that of building a website with ikiwiki from git.
+
+# We need a single worker. All pipeline steps are run on this worker,
+# over ssh. If we had more workers, and enough steps, the controller
+# would choose which one would run each step.
+workers:
+  localhost:
+    user: null
+    address: localhost
+    protocol: ssh
+
+# We likewise have a single project.
+projects:
+  obnam_www:
+    source:
+      subdir: .
+      type: git
+      url: ssh://git@git.liw.fi/obnam-www
+      branch: master
+    pipelines:
+      - name: build_and_publish_ikiwiki
+        triggered_by:
+          - source_change
+          - name: timer
+            interval: 1d
+        parameters:
+          rsync_dest: liw@pieni.net:/srv/www.obnam.org
+
+# We define here how source is retrieved for various version control
+# systems. The controller will run the get_all or update command to
+# freshen its copy of the source, and after it's done that, it checks
+# if pipelines get triggered. The freshening is done when it seems
+# like a trigger might be about to fire. Some env vars are defined by
+# the controller when running the shell snippets.
+source:
+  git:
+    get_all: |
+      git clone -b "$BRANCH" "$URL" "$SRCDIR"
+    update: |
+      cd "$SRCDIR" && git pull
+
+# Triggers define when a pipeline needds to run. Triggers are evaluated
+# whenever the source has been updated, or when there is external
+# stimuli, via an HTTP request to the controller
+# (http://controller/trigger/obnam_www/source_changed, which causes the
+# controller to freshen the source, and then evaluate the foo trigger).
+#
+# Each trigger is implemented by excuting a shell snippet, capturing and
+# storing its output. The trigger fires when the output is different
+# from the stored value.
+triggers:
+  source_change:
+    get_value: |
+      git show --pretty=oneline HEAD | head -n1
+  timer:
+    get_value: |
+      now="$(date +%s)
+      interval="$(get_parameter interval)"
+      next="$(echo "$STORED_VALUE" + "$interval")
+      if [ "$next" -lt "$now" ]
+      then
+          echo "$STORED_VALUE"
+      else
+          echo "$next"
+      fi
+
+# A pipeline is a list of steps to execute. It declares some
+# parameters that must be defined by the project. These are inherited
+# by each step. Also, the pipline may define variables whose values
+# get given to steps as parameters.
+pipelines:
+  build_and_publish_ikiwiki:
+    parameters:
+      - rsync_dest
+    variables:
+      htmldir: tmp.html
+    steps:
+      - run_ikiwiki
+      - run_rsync
+
+pipeline_steps:
+  run_ikiwiki:
+    parameters:
+      - htmldir
+    shell: |
+      tmp=tmp.setup
+      cat ikiwiki.setup > "$tmp"
+      echo "  srcdir: $(pwd)" >> "$tmp"
+      echo "  destdir: {{ htmldir }}" >> "$tmp"
+      rm -rf "{{ htmldir }}"
+      ikiwiki --setup "$tmp" --gettime --rebuild
+  run_rsync:
+    parameters:
+      - htmldir
+      - rsync_dest
+    shell: |
+      rsync -ahHSPs --delete "{{ htmldir }}/." "{{ rsync_dest }}/."

Fix filename
diff --git a/ick/ick2.mdwn b/ick/ick2.mdwn
index 702cc3e..cc428c0 100644
--- a/ick/ick2.mdwn
+++ b/ick/ick2.mdwn
@@ -222,7 +222,7 @@ shared by CI enthusiasts. I'm open to feedback.
 A non-useful visual representation
 ------------------------------------------------------------------------
 
-[[!img img2.svg]]
+[[!img ick2.svg]]
 
 
 Example configuration files

Include ick2.svg
diff --git a/ick/ick2.mdwn b/ick/ick2.mdwn
index ff2bd75..702cc3e 100644
--- a/ick/ick2.mdwn
+++ b/ick/ick2.mdwn
@@ -219,8 +219,14 @@ shared by CI enthusiasts. I'm open to feedback.
   artifacts, and related metadata gathered by the CI system.
 
 
+A non-useful visual representation
+------------------------------------------------------------------------
+
+[[!img img2.svg]]
+
+
 Example configuration files
----------------------------
+------------------------------------------------------------------------
 
 In this section I show some examples of how configuration files might
 work. Configuration files are in YAML, for human readability and

Add rudimentary .dot for ick2, plus output
diff --git a/ick/ick2.dot b/ick/ick2.dot
new file mode 100644
index 0000000..36b7cf9
--- /dev/null
+++ b/ick/ick2.dot
@@ -0,0 +1,26 @@
+digraph "ick2" {
+        USER [shape=box color=blue fontcolor=blue];
+        artifact_repo [shape=box color=blue fontcolor=blue];
+        VCS [shape=box color=blue fontcolor=blue];
+        STATUS [shape=box color=red fontcolor=red];
+
+        USER -> VCS [label="push"];
+        VCS -> controller;
+        timer -> controller;
+
+        VCS -> config;
+        config -> controller;
+        
+        controller -> worker_1 [label="data+cmds"];
+        controller -> worker_2 [label="data+cmds"];
+
+        controller -> reporter [label="trigger"];
+        controller -> STATUS;
+        STATUS -> controller;
+
+        webui -> controller [label="API request"];
+        USER -> webui [label="view+cmds"];
+
+        controller -> artifact_repo [label="publish"];
+        
+}
\ No newline at end of file
diff --git a/ick/ick2.svg b/ick/ick2.svg
new file mode 100644
index 0000000..3a19912
--- /dev/null
+++ b/ick/ick2.svg
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 2.38.0 (20140413.2041)
+ -->
+<!-- Title: ick2 Pages: 1 -->
+<svg width="487pt" height="399pt"
+ viewBox="0.00 0.00 487.35 399.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 395)">
+<title>ick2</title>
+<polygon fill="white" stroke="none" points="-4,4 -4,-395 483.347,-395 483.347,4 -4,4"/>
+<!-- USER -->
+<g id="node1" class="node"><title>USER</title>
+<polygon fill="none" stroke="blue" points="193,-391 139,-391 139,-355 193,-355 193,-391"/>
+<text text-anchor="middle" x="166" y="-369.3" font-family="Times,serif" font-size="14.00" fill="blue">USER</text>
+</g>
+<!-- VCS -->
+<g id="node3" class="node"><title>VCS</title>
+<polygon fill="none" stroke="blue" points="163,-304 109,-304 109,-268 163,-268 163,-304"/>
+<text text-anchor="middle" x="136" y="-282.3" font-family="Times,serif" font-size="14.00" fill="blue">VCS</text>
+</g>
+<!-- USER&#45;&gt;VCS -->
+<g id="edge1" class="edge"><title>USER&#45;&gt;VCS</title>
+<path fill="none" stroke="black" d="M157.481,-354.777C154.889,-349.183 152.159,-342.898 150,-337 147.316,-329.667 144.845,-321.572 142.751,-314.07"/>
+<polygon fill="black" stroke="black" points="146.112,-313.089 140.144,-304.334 139.35,-314.899 146.112,-313.089"/>
+<text text-anchor="middle" x="163" y="-325.8" font-family="Times,serif" font-size="14.00">push</text>
+</g>
+<!-- webui -->
+<g id="node11" class="node"><title>webui</title>
+<ellipse fill="none" stroke="black" cx="201" cy="-232" rx="32.4942" ry="18"/>
+<text text-anchor="middle" x="201" y="-228.3" font-family="Times,serif" font-size="14.00">webui</text>
+</g>
+<!-- USER&#45;&gt;webui -->
+<g id="edge12" class="edge"><title>USER&#45;&gt;webui</title>
+<path fill="none" stroke="black" d="M171.028,-354.95C172.665,-349.256 174.457,-342.867 176,-337 182.867,-310.882 190,-280.875 194.881,-259.827"/>
+<polygon fill="black" stroke="black" points="198.313,-260.519 197.149,-249.988 191.492,-258.946 198.313,-260.519"/>
+<text text-anchor="middle" x="212" y="-325.8" font-family="Times,serif" font-size="14.00">view+cmds</text>
+</g>
+<!-- artifact_repo -->
+<g id="node2" class="node"><title>artifact_repo</title>
+<polygon fill="none" stroke="blue" points="172,-36 86,-36 86,-0 172,-0 172,-36"/>
+<text text-anchor="middle" x="129" y="-14.3" font-family="Times,serif" font-size="14.00" fill="blue">artifact_repo</text>
+</g>
+<!-- controller -->
+<g id="node5" class="node"><title>controller</title>
+<ellipse fill="none" stroke="black" cx="181" cy="-105" rx="44.6926" ry="18"/>
+<text text-anchor="middle" x="181" y="-101.3" font-family="Times,serif" font-size="14.00">controller</text>
+</g>
+<!-- VCS&#45;&gt;controller -->
+<g id="edge2" class="edge"><title>VCS&#45;&gt;controller</title>
+<path fill="none" stroke="black" d="M121.48,-267.596C102.55,-242.656 74.0787,-195.812 94,-160 103.625,-142.698 121.342,-130.229 138.288,-121.664"/>
+<polygon fill="black" stroke="black" points="140.007,-124.724 147.568,-117.301 137.029,-118.389 140.007,-124.724"/>
+</g>
+<!-- config -->
+<g id="node7" class="node"><title>config</title>
+<ellipse fill="none" stroke="black" cx="136" cy="-178" rx="33.2948" ry="18"/>
+<text text-anchor="middle" x="136" y="-174.3" font-family="Times,serif" font-size="14.00">config</text>
+</g>
+<!-- VCS&#45;&gt;config -->
+<g id="edge4" class="edge"><title>VCS&#45;&gt;config</title>
+<path fill="none" stroke="black" d="M136,-267.969C136,-251.378 136,-225.883 136,-206.431"/>
+<polygon fill="black" stroke="black" points="139.5,-206.341 136,-196.341 132.5,-206.341 139.5,-206.341"/>
+</g>
+<!-- STATUS -->
+<g id="node4" class="node"><title>STATUS</title>
+<polygon fill="none" stroke="red" points="68,-36 0,-36 0,-0 68,-0 68,-36"/>
+<text text-anchor="middle" x="34" y="-14.3" font-family="Times,serif" font-size="14.00" fill="red">STATUS</text>
+</g>
+<!-- STATUS&#45;&gt;controller -->
+<g id="edge10" class="edge"><title>STATUS&#45;&gt;controller</title>
+<path fill="none" stroke="black" d="M68.1803,-35.5946C93.5073,-49.3409 127.516,-68.9329 151.63,-83.629"/>
+<polygon fill="black" stroke="black" points="149.999,-86.7349 160.349,-88.9994 153.67,-80.7748 149.999,-86.7349"/>
+</g>
+<!-- controller&#45;&gt;artifact_repo -->
+<g id="edge13" class="edge"><title>controller&#45;&gt;artifact_repo</title>
+<path fill="none" stroke="black" d="M170.726,-87.2067C163.297,-75.0621 153.123,-58.4315 144.681,-44.6326"/>
+<polygon fill="black" stroke="black" points="147.634,-42.7532 139.43,-36.0493 141.663,-46.4062 147.634,-42.7532"/>
+<text text-anchor="middle" x="179" y="-57.8" font-family="Times,serif" font-size="14.00">publish</text>
+</g>
+<!-- controller&#45;&gt;STATUS -->
+<g id="edge9" class="edge"><title>controller&#45;&gt;STATUS</title>
+<path fill="none" stroke="black" d="M152.969,-90.7188C128.436,-77.6038 92.9842,-57.294 67.0914,-41.6306"/>
+<polygon fill="black" stroke="black" points="68.7241,-38.5267 58.3651,-36.3035 65.0767,-44.5014 68.7241,-38.5267"/>
+</g>
+<!-- worker_1 -->
+<g id="node8" class="node"><title>worker_1</title>
+<ellipse fill="none" stroke="black" cx="234" cy="-18" rx="44.393" ry="18"/>
+<text text-anchor="middle" x="234" y="-14.3" font-family="Times,serif" font-size="14.00">worker_1</text>
+</g>
+<!-- controller&#45;&gt;worker_1 -->
+<g id="edge6" class="edge"><title>controller&#45;&gt;worker_1</title>
+<path fill="none" stroke="black" d="M191.54,-87.2785C195.178,-81.4938 199.275,-74.9664 203,-69 208.03,-60.9426 213.497,-52.1407 218.419,-44.1986"/>
+<polygon fill="black" stroke="black" points="221.403,-46.0272 223.692,-35.6826 215.452,-42.3418 221.403,-46.0272"/>
+<text text-anchor="middle" x="242.5" y="-57.8" font-family="Times,serif" font-size="14.00">data+cmds</text>
+</g>
+<!-- worker_2 -->
+<g id="node9" class="node"><title>worker_2</title>
+<ellipse fill="none" stroke="black" cx="340" cy="-18" rx="44.393" ry="18"/>
+<text text-anchor="middle" x="340" y="-14.3" font-family="Times,serif" font-size="14.00">worker_2</text>
+</g>
+<!-- controller&#45;&gt;worker_2 -->
+<g id="edge7" class="edge"><title>controller&#45;&gt;worker_2</title>
+<path fill="none" stroke="black" d="M216.849,-93.9584C235.426,-88.0142 258.114,-79.5698 277,-69 290.629,-61.3723 304.375,-50.865 315.534,-41.4506"/>
+<polygon fill="black" stroke="black" points="317.894,-44.0368 323.164,-34.8453 313.313,-38.7445 317.894,-44.0368"/>
+<text text-anchor="middle" x="330.5" y="-57.8" font-family="Times,serif" font-size="14.00">data+cmds</text>
+</g>
+<!-- reporter -->
+<g id="node10" class="node"><title>reporter</title>
+<ellipse fill="none" stroke="black" cx="441" cy="-18" rx="38.1938" ry="18"/>
+<text text-anchor="middle" x="441" y="-14.3" font-family="Times,serif" font-size="14.00">reporter</text>
+</g>
+<!-- controller&#45;&gt;reporter -->
+<g id="edge8" class="edge"><title>controller&#45;&gt;reporter</title>
+<path fill="none" stroke="black" d="M224.747,-100.553C262.913,-96.4186 319.191,-87.5596 365,-69 382.698,-61.8295 400.632,-50.2792 414.63,-40.0857"/>
+<polygon fill="black" stroke="black" points="416.895,-42.7619 422.8,-33.9653 412.698,-37.1595 416.895,-42.7619"/>
+<text text-anchor="middle" x="412.5" y="-57.8" font-family="Times,serif" font-size="14.00">trigger</text>
+</g>
+<!-- timer -->
+<g id="node6" class="node"><title>timer</title>
+<ellipse fill="none" stroke="black" cx="318" cy="-178" rx="29.795" ry="18"/>
+<text text-anchor="middle" x="318" y="-174.3" font-family="Times,serif" font-size="14.00">timer</text>
+</g>
+<!-- timer&#45;&gt;controller -->
+<g id="edge3" class="edge"><title>timer&#45;&gt;controller</title>
+<path fill="none" stroke="black" d="M295.989,-165.593C274.66,-154.539 241.947,-137.586 216.859,-124.584"/>
+<polygon fill="black" stroke="black" points="218.145,-121.308 207.656,-119.815 214.924,-127.523 218.145,-121.308"/>
+</g>
+<!-- config&#45;&gt;controller -->
+<g id="edge5" class="edge"><title>config&#45;&gt;controller</title>
+<path fill="none" stroke="black" d="M146.437,-160.533C151.923,-151.876 158.769,-141.076 164.916,-131.377"/>
+<polygon fill="black" stroke="black" points="167.91,-133.191 170.307,-122.871 161.997,-129.444 167.91,-133.191"/>
+</g>
+<!-- webui&#45;&gt;controller -->
+<g id="edge11" class="edge"><title>webui&#45;&gt;controller</title>
+<path fill="none" stroke="black" d="M198.261,-213.881C194.943,-193.146 189.312,-157.953 185.387,-133.422"/>
+<polygon fill="black" stroke="black" points="188.806,-132.634 183.77,-123.313 181.894,-133.74 188.806,-132.634"/>
+<text text-anchor="middle" x="228.5" y="-174.3" font-family="Times,serif" font-size="14.00">API request</text>
+</g>
+</g>
+</svg>

Add reports
diff --git a/ick/ick2.mdwn b/ick/ick2.mdwn
index ee1903e..ff2bd75 100644
--- a/ick/ick2.mdwn
+++ b/ick/ick2.mdwn
@@ -212,6 +212,12 @@ shared by CI enthusiasts. I'm open to feedback.
   actual working logic, and may be implemented in various ways,
   including command line and a web application.
 
+* The CI system may produce **reports**, whenever a pipeline has
+  finished running. A report is produced by code that is specified by
+  the user, and is triggered by a pipeline finishing, whether
+  successfully or not. The reporting code gets access to all runs,
+  artifacts, and related metadata gathered by the CI system.
+
 
 Example configuration files
 ---------------------------

Update ick2 based on feedback from Daniel
diff --git a/ick/ick2.mdwn b/ick/ick2.mdwn
index 8bda2c6..ee1903e 100644
--- a/ick/ick2.mdwn
+++ b/ick/ick2.mdwn
@@ -147,13 +147,19 @@ shared by CI enthusiasts. I'm open to feedback.
   where the source data is retrieved from, or what to do with the
   built artifacts.
 
-* A **pipeline step** is an atomic unit in a pipeline. For example, a
-  step might specify how to unpack the source code, build a release
-  tarball, or build a Debian binary package from a Debian source
-  package.
+* A **pipeline step** is an atomic unit in a pipeline template. For
+  example, a step might specify how to unpack the source code, build a
+  release tarball, or build a Debian binary package from a Debian
+  source package.
 
   Pipeline steps are specified in the CI configuration.
 
+  Pipeline steps may specify that they need a specific worker, or a
+  worker with specific attributes, on which to run.
+
+  Pipeline steps may be templated with parameters, just like
+  pipelines.
+
 * A **trigger** alerts the CI system that a pipeline may need to be
   run. For example, a pipeline might be triggered by a change in the
   version control repository, a timer elapsing, or another pipeline
@@ -199,7 +205,8 @@ shared by CI enthusiasts. I'm open to feedback.
   deleted afterwards, though this may be implemented via things like
   "git clean -fdxq", possibly.
 
-  FIXME: Should workspace be a checkout or an export?
+  A workspace be a checkout (`git clone`) or an exported copy (`git
+  archive`) of a version control system.
 
 * The **user interface** of the CI system is mostly detached from the
   actual working logic, and may be implemented in various ways,

Add a page for ick2 musings
diff --git a/ick/ick2.mdwn b/ick/ick2.mdwn
new file mode 100644
index 0000000..8bda2c6
--- /dev/null
+++ b/ick/ick2.mdwn
@@ -0,0 +1,353 @@
+[[!meta title="On developing ick to be my dream CI/CD system"]]
+
+Introduction
+============================================================================
+
+It is 2016. A good continuous integration system is an essential tool
+for software development. Most programmers wouldn't develop software
+without using a version control system or writing unit tests, and CI
+is now another of the basic tools in a toolbox for programming.
+
+I've been using CI since about 2011 for my own projects. Initially, I
+used Jenkins, but after a few years, it irritated me enough that got
+ennough, and wrote my own, which is called Ick. What irritated me
+about Jenkins was particularly that it broke in one way or another
+several times a year, and I'd need to fix it, sometimes by starting
+off from scratch. I was also annoyed by the fact that it tooks quite
+some wrangling to get Jenkins set up so that it could cleanly build
+Debian packages for me, for each of my many personal projects. I
+worked around that by writing a tool to set up Jenkins jobs, and
+triggering them, via the Jenkins API. Towards the end I had about 500
+jobs and was reasonably happy. Until Jenkins broke one time too many.
+
+In the interest of fairness, I'll admit that Jenkins works well enough
+for a lot of people and projects. I'm not saying Jenkins is uselessly
+bad for everyone, but it and I have differences of opionion about a
+few things, which means I'm more likely to be happy with another tool.
+
+Ick is what I currently use. It started as a quick hack, and it's
+aimed at me. It isn't a service that runs continuously. It's a command
+line tool I write when I think it's time. It's also designed around my
+personal resource contraints at the time I was building it. Primarily
+this means it only runs one build at a time, rather than trying to run
+as many things in parallel as possible, since I only had my laptop
+back then.
+
+While Ick works for me, and I'm mostly OK with it, it's clumsy and
+slow, and doesn't work very well for anyone else. It's also a bit
+fragile, and fixing things like the build steps to run requires
+changing its source code. I would like to have something better, and
+if I go into the effort of writing that, I'd like it to be as close to
+my dream system as possible.
+
+This document is the start of that work.
+
+Other CI systems
+----------------------------------------------------------------------------
+
+I've not tried all the CI systems in the world. In fact, I've only
+really tried Jenkins in anger. I've looked a little into a few others,
+and since I'm looking for a system to be happy with, I've managed to
+find fatal flaws in all the ones I've looked at.
+
+In order to generate a lot of angry commentary, here's a few notes:
+
+* Buildbot seems to be configured using Python scripts. I want
+  configuration to be statically analysable. If I have to run
+  arbitrary code to know what will happen, I'm unhappy.
+
+* Go seems interesting in many ways. However, it's written in Java
+  (which I don't like and don't want to debug), and while it's open
+  source, the project requires patch submitters to sign a CLA, which I
+  won't. If I chose Go, I'd not be to improve the software.
+
+* ... I'm sure I've looked at other systems. FIXME.
+
+
+What I think I want from a CI system
+============================================================================
+
+In this chapter I'm trying to draw a picture of what kind of CI system
+I think I would be happy with.
+
+What a CI system is
+----------------------------------------------------------------------------
+
+The purpose of a CI system is to take some source code and make sure
+it works. As a side effect it should produce some artifacts, which
+would include installation packages, formatted manuals, and possibly
+other things, depending in the project in question.
+
+One can think of a CI system as a thing that waits for something to
+trigger it, and once triggered, runs a sequence of steps (known as the
+pipeline) to produce the desired results. In its most simple form, a
+CI system just runs a sequence of Unix shell commands if if anything
+changes in a version control repository.
+
+What about CD?
+----------------------------------------------------------------------------
+
+An extension of a continuous integration system is a continuous
+delivery (or deployment) system, or CD for short. This would take the
+installation packages produced by the CI part and either make them
+available for anyone to use, or even install them onto production
+servers. Using a CD system requires a development workflow where the
+time to production is mimimization goal.
+
+From a CI implementataion point of view, I think there's not a whole
+lot of difference between CI and CD. CD means adding more steps to the
+"pipeline" that is run on every change, in order to do the delivery or
+deployment.
+
+What a CI/CD system doesn't need to be
+----------------------------------------------------------------------------
+
+A CI/CD system doesn't need to manage its various component systems,
+or other systems, or do other system administration tasks. It might be
+configured to do those, but the knowledge should be in the
+configuration and doesn't need to be baked into the code.
+
+FIXME. There's more that can be placed out of scope.
+
+
+Concepts
+============================================================================
+
+In this chapter I'm defining various core concepts for a CI system.
+This is highly biased by my vision for a CI system and might not be
+shared by CI enthusiasts. I'm open to feedback.
+
+* **CI configuration** specifies how a CI instance should work: what
+  projects it should build, how, when, etc. The configuration is
+  stored in static files in version control.
+
+* A **project** represents a thing that is being developed. For
+  example, it might be a program, a website, or a document. A project
+  consists of some source data, one or more pipelines to build
+  artifacts from the source, with some triggers that cause the
+  pipelines to run. The CI configuration specifies the projects and
+  their various aspects.
+
+* A **version control repository** is where project source code is
+  stored. It is one of the ways in which source data can be provided
+  to the CI system. As an example, git. Personally, git is the only
+  interesting one, but I'd prefer to not code in an assumption that it
+  is git. It should be fairly easy to support any reasonable version
+  control system.
+
+  A project source data may reside in multiple version control
+  repositories, which get stacked. For example, Debian packaging might
+  be in a separate repository from upstream source code.
+
+* A **pipeline** instance is a pipeline template with parameters to
+  nail down any variations for a specific project.
+
+* A **pipeline template** specifies the steps to take to turn source
+  data into output artifacts. A template typically parameters, such as
+  where the source data is retrieved from, or what to do with the
+  built artifacts.
+
+* A **pipeline step** is an atomic unit in a pipeline. For example, a
+  step might specify how to unpack the source code, build a release
+  tarball, or build a Debian binary package from a Debian source
+  package.
+
+  Pipeline steps are specified in the CI configuration.
+
+* A **trigger** alerts the CI system that a pipeline may need to be
+  run. For example, a pipeline might be triggered by a change in the
+  version control repository, a timer elapsing, or another pipeline
+  finishing successfully.
+
+* The **CI controller** decides when to run each step in each pipeline
+  and on which worker and what to do if something fails. The
+  controller is probably a daemon that can be queries and controlled
+  via an HTTP API.
+
+* A **CI worker** runs each pipeline step. Each worker gets commands
+  from the controller, and returns results to the controller. Workers
+  have names, and attributes (key/value pairs), and pipelines or their
+  steps may be restricted to specific workers or types of workers.
+
+  Communication with workers is probably purely over ssh. Workers
+  should not be required to have anything much installed, apart from
+  an ssh server.
+
+* An **artifact repository** is where outputs from the build processes
+  get stored. A CI system might any number of artifact repositories:
+  for example, if it builds both Debian and RPM packages, they would
+  be stored in different repositories.
+
+* **Pipeline output** is everything produced by running a pipeline
+  that isn't explicit artifacts. For example, the build log (output
+  from all the commands run by the pipeline), measurements of resource
+  usage, etc.
+
+* A **project dependency** is another project, which is needed to
+  build a specific project.
+
+* A **pipeline parameter** is used to create a pipeline instance from
+  a pipeline template, and fixes a generic value for the template in a
+  manner suitable for the specific project.
+
+* A **workspace** is the directory where pipeline steps are run. It is
+  initially populated with the source data, and nothing else. Each

(Diff truncated)
Add link to ChaosKey to links page
diff --git a/links.mdwn b/links.mdwn
index b20e104..5cda482 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -57,6 +57,7 @@ incarnation of that web page.
 [N40L](http://n40l.wikia.com/wiki/HP_MicroServer_N40L_Wiki)
 [Lenovo PSREF](http://lenovo.com/psref/)
 [Tuxedo](http://www.tuxedocomputers.com/)
+[ChaosKey](http://altusmetrum.org/ChaosKey/)
 
 **Computer stores:**
 [crucial](http://www.crucial.com/uk/index.aspx)

Typo fix from tbm
diff --git a/manpages.mdwn b/manpages.mdwn
index d6fc62b..d69515d 100644
--- a/manpages.mdwn
+++ b/manpages.mdwn
@@ -294,7 +294,7 @@ pages. Here's an example of an example:
 
 A few new `troff` commands:
 
-* `.nf` turns of paragraph filling mode: we don't want that for
+* `.nf` turns off paragraph filling mode: we don't want that for
   showing command lines.
 * `.fi` turns it back on.
 * `.RS` starts a relative margin indent: examples are more visually

Update ttystatus bug tracking info
diff --git a/ttystatus.mdwn b/ttystatus.mdwn
index 8a508a8..5af7c09 100644
--- a/ttystatus.mdwn
+++ b/ttystatus.mdwn
@@ -28,4 +28,3 @@ See also:
 * [API documentation](http://code.liw.fi/ttystatus/docs/)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ttystatus/>
 * Git clone: `git://git.liw.fi/ttystatus/`
-* [[Bug tracking page|ttystatus/bugs]]
diff --git a/ttystatus/bugs.mdwn b/ttystatus/bugs.mdwn
index 43b3ecd..32e752f 100644
--- a/ttystatus/bugs.mdwn
+++ b/ttystatus/bugs.mdwn
@@ -1,6 +1,8 @@
 Open bugs in ttystatus
 ==================
 
+See [[code]] for current bug tracker.
+
 See also bugs that are [[done]].
 
 [[!inline pages="page(ttystatus/bugs/*) and 

Update python-tracing bug tracking info
diff --git a/tracing.mdwn b/tracing.mdwn
index 4577117..d546ea9 100644
--- a/tracing.mdwn
+++ b/tracing.mdwn
@@ -26,4 +26,3 @@ See also:
 * [Documentation](http://code.liw.fi/python-tracing/docs/)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/python-tracing/>
 * Git clone: `git://git.liw.fi/python-tracing/`
-* [[Bugs]]
diff --git a/tracing/bugs.mdwn b/tracing/bugs.mdwn
index ba6493b..5b6e425 100644
--- a/tracing/bugs.mdwn
+++ b/tracing/bugs.mdwn
@@ -1,6 +1,8 @@
 Open bugs in tracing
 ==================
 
+See [[code]] for current bug tracker.
+
 See also bugs that are [[done]].
 
 [[!inline pages="page(tracing/bugs/*) and 

Update summain bug tracking info
diff --git a/summain.mdwn b/summain.mdwn
index 63aab2a..c0f9863 100644
--- a/summain.mdwn
+++ b/summain.mdwn
@@ -13,4 +13,3 @@ See also:
 * [manpage](http://code.liw.fi/summain/summain.1.txt)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/summain/>
 * Git clone: `git://git.liw.fi/summain/`
-* [[Bugs]]
diff --git a/summain/bugs.mdwn b/summain/bugs.mdwn
index 73ed71b..4465f48 100644
--- a/summain/bugs.mdwn
+++ b/summain/bugs.mdwn
@@ -1,6 +1,8 @@
 Open bugs in summain
 ==================
 
+See [[code]] for current bug tracker.
+
 See also bugs that are [[done]].
 
 [[!inline pages="page(summain/bugs/*) and 

Update larch bug tracking info
diff --git a/larch.mdwn b/larch.mdwn
index dda00d1..d44a85b 100644
--- a/larch.mdwn
+++ b/larch.mdwn
@@ -58,7 +58,6 @@ to change anymore.
 * [API documentation](http://code.liw.fi/larch/docs/)
 * [[Benchmark results|benchmarks]]
 * [[Release checklist|larch/release]]
-* [[Bug tracking page|larch/bugs]]
 * Blog entries: <http://blog.liw.fi/tag/larch/>
 * [[Private journal entries|/obnam/journal-dump]]
 * Copyright license: GNU GPL3 or later.
diff --git a/larch/bugs.mdwn b/larch/bugs.mdwn
index e34fc97..0e80e4e 100644
--- a/larch/bugs.mdwn
+++ b/larch/bugs.mdwn
@@ -1,6 +1,8 @@
 Open bugs in Larch
 ==================
 
+See [[code]] for current bug tracker.
+
 See also bugs that are [[done]].
 
 [[!inline pages="page(larch/bugs/*) and 

Update genbackupdata bug tracking info
diff --git a/genbackupdata.mdwn b/genbackupdata.mdwn
index d8fdb4c..9e86ca6 100644
--- a/genbackupdata.mdwn
+++ b/genbackupdata.mdwn
@@ -8,4 +8,3 @@ genbackupdata is a program to generate test data for backup software testing.
 * [manpage](http://code.liw.fi/genbackupdata/genbackupdata.1.txt)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/genbackupdata/>
 * Git clone: `git://git.liw.fi/genbackupdata/`
-* [[Bugs]]
diff --git a/genbackupdata/bugs.mdwn b/genbackupdata/bugs.mdwn
index f095895..b337a17 100644
--- a/genbackupdata/bugs.mdwn
+++ b/genbackupdata/bugs.mdwn
@@ -1,6 +1,8 @@
 Open bugs in genbackupdata
 ==================
 
+See [[code]] for current bug tracker.
+
 See also bugs that are [[done]].
 
 [[!inline pages="page(genbackupdata/bugs/*) and 

Update extrautils bug tracking info
diff --git a/extrautils.mdwn b/extrautils.mdwn
index 1d167f0..fc8fe6c 100644
--- a/extrautils.mdwn
+++ b/extrautils.mdwn
@@ -15,4 +15,3 @@ See also:
 * [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/extrautils/tree/NEWS)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/extrautils/>
 * Git clone: `git://git.liw.fi/extrautils/`
-* [[Bugs]]
diff --git a/extrautils/bugs.mdwn b/extrautils/bugs.mdwn
index 3673b55..707a280 100644
--- a/extrautils/bugs.mdwn
+++ b/extrautils/bugs.mdwn
@@ -1,6 +1,8 @@
 Open bugs in extrautils
 ==================
 
+See [[code]] for current bug tracker.
+
 See also bugs that are [[done]].
 
 [[!inline pages="page(extrautils/bugs/*) and 

Update dupfiles bug tracking info
diff --git a/dupfiles.mdwn b/dupfiles.mdwn
index 94fcf22..085864d 100644
--- a/dupfiles.mdwn
+++ b/dupfiles.mdwn
@@ -23,7 +23,6 @@ See also:
 * [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/dupfiles/tree/NEWS)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/dupfiles/>
 * Git clone: `git://git.liw.fi/dupfiles/`
-* [[Bugs]]
 
 Benchmark results
 -----------------
diff --git a/dupfiles/bugs.mdwn b/dupfiles/bugs.mdwn
index 5539168..8487143 100644
--- a/dupfiles/bugs.mdwn
+++ b/dupfiles/bugs.mdwn
@@ -1,6 +1,8 @@
 Open bugs in dupfiles
 ==================
 
+See [[code]] for current bug tracker.
+
 See also bugs that are [[done]].
 
 [[!inline pages="page(dupfiles/bugs/*) and 

Update coverage-test-runner bug tracking info
diff --git a/coverage-test-runner.mdwn b/coverage-test-runner.mdwn
index b60f20c..b76687e 100644
--- a/coverage-test-runner.mdwn
+++ b/coverage-test-runner.mdwn
@@ -36,4 +36,3 @@ option) any later version.
 * [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/coverage-test-runner/tree/NEWS)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/coverage-test-runner/>
 * Git clone: `git://git.liw.fi/coverage-test-runner/`
-* [[Bugs]]
diff --git a/coverage-test-runner/bugs.mdwn b/coverage-test-runner/bugs.mdwn
index 8bb2680..6d58b02 100644
--- a/coverage-test-runner/bugs.mdwn
+++ b/coverage-test-runner/bugs.mdwn
@@ -1,6 +1,8 @@
 Open bugs in coverage-test-runner
 ==================
 
+See [[code]] for current bug tracking.
+
 See also bugs that are [[done]].
 
 [[!inline pages="page(coverage-test-runner/bugs/*) and 

Update cmdtest page to use new ticketing system
diff --git a/cmdtest.mdwn b/cmdtest.mdwn
index 7c1bce3..13d59e9 100644
--- a/cmdtest.mdwn
+++ b/cmdtest.mdwn
@@ -13,4 +13,3 @@ If not, it reports a problem, and shows the differences.
 * Git clone: `git://git.liw.fi/cmdtest/`
 * [cmdtest manpage](http://code.liw.fi/cmdtest/cmdtest.1.txt)
 * [yarn manpage](http://code.liw.fi/cmdtest/yarn.1.txt)
-* [[Bugs]]
diff --git a/cmdtest/bugs.mdwn b/cmdtest/bugs.mdwn
index 93cd4c8..1b0fecc 100644
--- a/cmdtest/bugs.mdwn
+++ b/cmdtest/bugs.mdwn
@@ -1,6 +1,8 @@
 Open bugs in cmdtest
 ==================
 
+See [[code]] for current bug tracker.
+
 See also bugs that are [[done]].
 
 [[!inline pages="page(cmdtest/bugs/*) and 

Move cliapp bugs to bugs.liw.fi
diff --git a/cliapp.mdwn b/cliapp.mdwn
index 73ccb1a..820e2ae 100644
--- a/cliapp.mdwn
+++ b/cliapp.mdwn
@@ -14,4 +14,3 @@ compatible ways.
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cliapp/>
 * Git clone: `git://git.liw.fi/cliapp/`
 * [API documentation](http://code.liw.fi/cliapp/docs/)
-* [[Bugs]]
diff --git a/cliapp/bugs.mdwn b/cliapp/bugs.mdwn
index 6620623..06a99f1 100644
--- a/cliapp/bugs.mdwn
+++ b/cliapp/bugs.mdwn
@@ -1,6 +1,8 @@
 Open bugs in cliapp
 ==================
 
+See [[code]] for current bug tracker.
+
 See also bugs that are [[done]].
 
 [[!inline pages="page(cliapp/bugs/*) and 

Update location of bug tracker for my projects
diff --git a/code.mdwn b/code.mdwn
index 41110f8..1126036 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -41,6 +41,6 @@ the usual Web of Trust mechanisms.
 Bug trackers
 ------------
 
-I use this wiki for bug tracking. Each project has a link to its bug
-list, if any. Most of the time I prefer you to report the issue or bug
-by e-mail, and I'll add it to the wiki myself.
+I use [[distix]] for bug tracking. The web view of tickets is at
+<http://bugs.liw.fi/>. To send mail to distix, mail to bugs at my
+domain.

Fix PGP key info
diff --git a/contact.mdwn b/contact.mdwn
index 72c20de..8da766d 100644
--- a/contact.mdwn
+++ b/contact.mdwn
@@ -3,5 +3,5 @@
 My public contact data is available as a [vCard](http://files.liw.fi/liw.vcf).
 
 * E-mail: [liw@liw.fi](mailto:liw@liw.fi)
-* PGP: 5E8511F9 (old key 2D9ACC8E still works, too)
+* PGP: DBE5 439D 97D8 2626 64A1  B018 44E1 7740 B861 1E9C
 * IRC: `liw` on IRCnet, OFTC, and Freenode

Move summain manpage to code.liw.fi
diff --git a/summain.mdwn b/summain.mdwn
index 3705407..63aab2a 100644
--- a/summain.mdwn
+++ b/summain.mdwn
@@ -10,7 +10,7 @@ See also:
 
 * [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/summain/tree/README)
 * [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/summain/tree/NEWS)
-* [[manpage|summain.1.txt]]
+* [manpage](http://code.liw.fi/summain/summain.1.txt)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/summain/>
 * Git clone: `git://git.liw.fi/summain/`
 * [[Bugs]]
diff --git a/summain/summain.1.txt b/summain/summain.1.txt
deleted file mode 100644
index 7ff82e7..0000000
--- a/summain/summain.1.txt
+++ /dev/null
@@ -1,149 +0,0 @@
-SUMMAIN(1)                                                          SUMMAIN(1)
-
-
-
-NAME
-       summain - gather file checksums and metadata
-
-SYNOPSIS
-       summain     [-c=CHECKSUM]     [--checksum=CHECKSUM]     [--config=FILE]
-       [--dump-config]  [--dump-memory-profile=METHOD]  [--dump-setting-names]
-       [--exclude=FIELD]     [--generate-manpage=TEMPLATE]    [-h]    [--help]
-       [--help-all]    [--list-config-files]    [--log=FILE]    [--log-keep=N]
-       [--log-level=LEVEL]     [--log-max=SIZE]     [--log-mode=MODE]     [-m]
-       [--mangle-paths]                       [--memory-dump-interval=SECONDS]
-       [--no-default-configs]     [--no-mangle-paths]    [--no-relative-paths]
-       [--output=FILE] [-f=OUTPUT-FORMAT] [--output-format=OUTPUT-FORMAT] [-r]
-       [--relative-paths] [--secret=SECRET] [--version] [FILE]...
-
-DESCRIPTION
-       summain gathers metadata about files, and computes their checksums.  It
-       is intended to create a manifest of the files.   The  manifest  can  be
-       used to see if something has changed: a new manifest can be created and
-       compared with the old one with diff(1).
-
-       The manifest looks like this:
-
-              Name: foo/bar/foobar
-              SHA1: 1234123413241324
-              Mtime: 2010-01-01 02:08:00.127651 +0000
-              Mode: 1755
-
-       The filename is URL-encoded to ensure it is purely ASCII.  Mode  is  in
-       octal.
-
-       Only  some  inode  fields are included.  It does not make sense to com-
-       pare, for example, the access time, so that is not included.
-
-       Time stamps are given using microsecond precision, for the  benefit  of
-       those  filesystems  that  can  support  precise timestamps.  (Should be
-       nanosecond,  but  Python  return  timestamps  as  floating  point,  and
-       nanosecond precision is too much for the floating point type.)
-
-       The  inode  and  device  number fields will not be reported accurately.
-       Instead, they are normalized so that manifests  are  useful  after  the
-       files have been restored from backups.  Accurate numbers would mean ev-
-       erything seems to have changed.  Normalized means that there will be no
-       differences.   The  numbers  are  reported  so  that  hard links can be
-       checked.
-
-       Directories named on the command line will be recursed automatically.
-
-OPTIONS
-       -c, --checksum=CHECKSUM
-              which checksums to compute: MD5, SHA1, SHA224,  SHA256,  SHA384,
-              SHA512; use once per checksum type (default is SHA1)
-
-       --exclude=FIELD
-              do not output or compute FIELD
-
-       --generate-manpage=TEMPLATE
-              SUPPRESSHELP
-
-       -h, --help
-              show this help message and exit
-
-       -m, --mangle-paths
-              mangle (obfuscate) paths
-
-       --no-mangle-paths
-
-
-       --no-relative-paths
-
-
-       --output=FILE
-              write output to FILE, instead of standard output
-
-       -f, --output-format=OUTPUT-FORMAT
-              choose output format (rfc822, csv, json)
-
-       -r, --relative-paths
-              print paths relative to arguments
-
-       --secret=SECRET
-              use SECRET to make mangled paths unguessable
-
-       --version
-              show program's version number and exit
-
-   Configuration files and settings
-       --config=FILE
-              add FILE to config files
-
-       --dump-config
-              write out the entire current configuration
-
-       --dump-setting-names
-              SUPPRESSHELP
-
-       --help-all
-              show all options
-
-       --list-config-files
-              SUPPRESSHELP
-
-       --no-default-configs
-              clear list of configuration files to read
-
-   Logging
-       --log=FILE
-              write  log entries to FILE (default is to not write log files at
-              all); use "syslog" to log to system log, or  "none"  to  disable
-              logging
-
-       --log-keep=N
-              keep last N logs (10)
-
-       --log-level=LEVEL
-              log  at LEVEL, one of debug, info, warning, error, critical, fa-
-              tal (default: debug)
-
-       --log-max=SIZE
-              rotate logs larger than SIZE, zero for never (default: 0)
-
-       --log-mode=MODE
-              set permissions of new log files to MODE (octal; default 0600)
-
-   Peformance
-       --dump-memory-profile=METHOD
-              make memory profiling dumps using METHOD, which is one of: none,
-              simple, meliae, or heapy (default: simple)
-
-       --memory-dump-interval=SECONDS
-              make memory profiling dumps at least SECONDS apart
-
-EXAMPLE
-       To  make  a complete manifest of a directory tree so that you can later
-       verify that nothing at all has changed:
-
-              summain foo > foo.summain
-
-       To verify that nothing has changed:
-
-              summain foo > foo.summain-2
-              diff -u foo.summain foo.summain-2
-
-
-
-                                                                    SUMMAIN(1)

Add links to ick manuals
diff --git a/ick.mdwn b/ick.mdwn
index c6eee9f..ed06849 100644
--- a/ick.mdwn
+++ b/ick.mdwn
@@ -6,5 +6,8 @@ needs. You probably want something else instead.
 
 * [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ick/tree/README)
 * [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ick/tree/NEWS)
+* manual:
+  [HTML](http://code.liw.fi/ick/ick-manual.ci.html),
+  [PDF](http://code.liw.fi/ick/ick-manual.ci.pdf)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ick/>
 * Git clone: `git://git.liw.fi/ick/`

Move genbackupdata manpage to code.liw.fi
diff --git a/genbackupdata.mdwn b/genbackupdata.mdwn
index 9220fe8..d8fdb4c 100644
--- a/genbackupdata.mdwn
+++ b/genbackupdata.mdwn
@@ -5,7 +5,7 @@ genbackupdata is a program to generate test data for backup software testing.
 
 * [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/genbackupdata/tree/README)
 * [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/genbackupdata/tree/NEWS)
-* [[manpage|genbackupdata.1.txt]]
+* [manpage](http://code.liw.fi/genbackupdata/genbackupdata.1.txt)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/genbackupdata/>
 * Git clone: `git://git.liw.fi/genbackupdata/`
 * [[Bugs]]
diff --git a/genbackupdata/genbackupdata.1.txt b/genbackupdata/genbackupdata.1.txt
deleted file mode 100644
index 3ef0ac9..0000000
--- a/genbackupdata/genbackupdata.1.txt
+++ /dev/null
@@ -1,146 +0,0 @@
-GENBACKUPDATA(1)	    General Commands Manual	      GENBACKUPDATA(1)
-
-
-
-NAME
-       genbackupdata - generate backup test data
-
-SYNOPSIS
-       genbackupdata   [--chunk-size=SIZE]   [--config=FILE]   [--dump-config]
-       [--dump-setting-names]  [--generate-manpage=TEMPLATE]   [-h]   [--help]
-       [--help-all]  [--list-config-files]  [--version] [--no-default-configs]
-       [-cSIZE] [--create=SIZE] [--depth=DEPTH] [--dump-memory-profile=METHOD]
-       [--file-size=SIZE]   [--log=FILE]   [--log-keep=N]  [--log-level=LEVEL]
-       [--log-max=SIZE]       [--log-mode=MODE]        [--max-files=MAX-FILES]
-       [--memory-dump-interval=SECONDS] [--output=FILE] [--quiet] [--no-quiet]
-       [--seed=SEED] [FILE]...
-
-DESCRIPTION
-       genbackupdata generates test data sets for performance testing of back‐
-       up  software.  It creates a directory tree filled with files of differ‐
-       ent sizes.  The total size and the distribution of sizes between  small
-       and  big are configurable.  The program can also modify an existing di‐
-       rectory tree by creating new files, and deleting, renaming, or  modify‐
-       ing existing files.  This can be used to generate test data for succes‐
-       sive generations of backups.
-
-       The program is deterministic: with a given set  of  parameters  (and  a
-       given  pre-existing directory tree), it always creates the same output.
-       This way, it is possible to reproduce  backup  tests  exactly,  without
-       having to distribute the potentially very large test sets.
-
-       The data set consists of plain files and directories.  Files are either
-       small text files or big binary files.  Text files  contain  the	"lorem
-       ipsum"  stanza,	binary	files contain randomly generated byte streams.
-       The percentage of file data that is small text or big binary files  can
-       be set, as can the sizes of the respective file types.
-
-       Files  and  directories are named "fileXXXX" or "dirXXXX", where "XXXX"
-       is a successive integer, separate successions for  files  and  directo‐
-       ries.   There  is an upper limit to how many files a directory may con‐
-       tain.  After the file limit is reached, a new sub-directory is created.
-       The first set of files go into the root directory of the test set.
-
-       You  have  to  give one of the options --create, --delete, --rename, or
-       --modify for the program to do anything.  You can, however,  give  more
-       than  one of them, if DIR already exists.  (Giving the same option more
-       than once means that only the last instance is counted.)  (DIR) is cre‐
-       ated if it doesn't exist already.
-
-OPTIONS
-       --chunk-size=SIZE
-	      generate data in chunks of this size
-
-       -c, --create=SIZE
-	      how much data to create (default: 0)
-
-       --depth=DEPTH
-	      depth of directory tree
-
-       --file-size=SIZE
-	      size of one file
-
-       --generate-manpage=TEMPLATE
-	      SUPPRESSHELP
-
-       -h, --help
-	      show this help message and exit
-
-       --max-files=MAX-FILES
-	      max files/dirs per dir
-
-       --output=FILE
-	      write output to FILE, instead of standard output
-
-       --quiet
-	      do not report progress
-
-       --no-quiet
-	      opposite of --quiet
-
-       --seed=SEED
-	      seed for random number generator
-
-       --version
-	      show program's version number and exit
-
-   Configuration files and settings
-       --config=FILE
-	      add FILE to config files
-
-       --dump-config
-	      write out the entire current configuration
-
-       --dump-setting-names
-	      SUPPRESSHELP
-
-       --help-all
-	      show all options
-
-       --list-config-files
-	      SUPPRESSHELP
-
-       --no-default-configs
-	      clear list of configuration files to read
-
-   Logging
-       --log=FILE
-	      write  log entries to FILE (default is to not write log files at
-	      all); use "syslog" to log to system log, "stderr" to log to  the
-	      standard error output, or "none" to disable logging
-
-       --log-keep=N
-	      keep last N logs (10)
-
-       --log-level=LEVEL
-	      log  at LEVEL, one of debug, info, warning, error, critical, fa‐
-	      tal (default: debug)
-
-       --log-max=SIZE
-	      rotate logs larger than SIZE, zero for never (default: 0)
-
-       --log-mode=MODE
-	      set permissions of new log files to MODE (octal; default 0600)
-
-   Peformance
-       --dump-memory-profile=METHOD
-	      make memory profiling dumps using METHOD, which is one of: none,
-	      simple, or meliae (default: simple)
-
-       --memory-dump-interval=SECONDS
-	      make memory profiling dumps at least SECONDS apart
-
-EXAMPLES
-       Create data for the first generation of a backup:
-
-	      genbackupdata --create=10G testdir
-
-       Modify an existing set of backup data to create a new generation:
-
-	      genbackupdata -c 5% -d 2% -m 5% -r 0.5% testdir
-
-       The above command can be run for each new generation.
-
-
-
-							      GENBACKUPDATA(1)

Add link copyright-statement-lint manpage
diff --git a/copyright-statement-lint.mdwn b/copyright-statement-lint.mdwn
index b4900c0..66b036f 100644
--- a/copyright-statement-lint.mdwn
+++ b/copyright-statement-lint.mdwn
@@ -8,5 +8,6 @@ any of the statements you do have.
 
 * [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/copyright-statement-lint/tree/README)
 * [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/copyright-statement-lint/tree/NEWS)
+* [manpage](http://code.liw.fi/copyright-statement-lint/copyright-statement-lint.1.txt)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/copyright-statement-lint/>
 * Git clone: `git://git.liw.fi/copyright-statement-lint/`

Move cmdtest/yarn manpages to code.liw.fi
diff --git a/cmdtest.mdwn b/cmdtest.mdwn
index cbcd1fc..7c1bce3 100644
--- a/cmdtest.mdwn
+++ b/cmdtest.mdwn
@@ -11,6 +11,6 @@ If not, it reports a problem, and shows the differences.
 * [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cmdtest/tree/NEWS)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cmdtest/>
 * Git clone: `git://git.liw.fi/cmdtest/`
-* [[cmdtest manpage|cmdtest.1.txt]]
-* [[yarn manpage|yarn.1.txt]]
+* [cmdtest manpage](http://code.liw.fi/cmdtest/cmdtest.1.txt)
+* [yarn manpage](http://code.liw.fi/cmdtest/yarn.1.txt)
 * [[Bugs]]
diff --git a/cmdtest/cmdtest.1.txt b/cmdtest/cmdtest.1.txt
deleted file mode 100644
index 2de3efd..0000000
--- a/cmdtest/cmdtest.1.txt
+++ /dev/null
@@ -1,221 +0,0 @@
-CMDTEST(1)		    General Commands Manual		    CMDTEST(1)
-
-
-
-NAME
-       cmdtest - blackbox testing of Unix command line tools
-
-SYNOPSIS
-       cmdtest	    [-c=COMMAND]      [--command=COMMAND]      [--config=FILE]
-       [--dump-config]	[--dump-memory-profile=METHOD]	[--dump-setting-names]
-       [--generate-manpage=TEMPLATE]  [-h] [--help] [--help-all] [-k] [--keep]
-       [--list-config-files] [--log=FILE]  [--log-keep=N]  [--log-level=LEVEL]
-       [--log-max=SIZE]   [--log-mode=MODE]   [--memory-dump-interval=SECONDS]
-       [--no-default-configs]	[--no-keep]   [--no-timings]   [--output=FILE]
-       [-t=TEST] [--test=TEST] [--timings] [--version] [FILE]...
-
-DESCRIPTION
-       cmdtest	black  box  tests  Unix  command  line tools.  Given some test
-       scripts, their inputs, and expected outputs, it verifies that the  com‐
-       mand  line  produces the expected output.  If not, it reports problems,
-       and shows the differences.
-
-       Each test case foo consists of the following files:
-
-       foo.script
-	      a script to run the test (this is required)
-
-       foo.stdin
-	      the file fed to standard input
-
-       foo.stdout
-	      the expected output to the standard output
-
-       foo.stderr
-	      the expected output to the standard error
-
-       foo.exit
-	      the expected exit code
-
-       foo.setup
-	      a shell script to run before the test
-
-       foo.teardown
-	      a shell script to run after test
-
-       Usually, a single test is not enough. All tests are put into  the  same
-       directory, and they may share some setup and teardown code:
-
-       setup-once
-	      a shell script to run once, before any tests
-
-       setup  a shell script to run before each test
-
-       teardown
-	      a shell script to run after each test
-
-       teardown-once
-	      a shell script to run once, after all tests
-
-       cmdtest	is given the name of the directory with all the tests, or sev‐
-       eral such directories, and it does the following:
-
-       · execute setup-once
-
-       · for each test case (unique prefix foo):
-
-	      — execute setup
-
-	      — execute foo.setup
-
-	      — execute the command, by running foo.script, and redirecting
-		standard input to come from foo.stdin, and capturing standard
-		output and error and exit codes
-
-	      — execute foo.teardown
-
-	      — execute teardown
-
-	      — report result of test: does exit code match foo.exit, standard
-		output match foo.stdout, and standard error match foo.stderr?
-
-       · execute teardown-once
-
-       Except for foo.script, all of these files are optional.	If a setup or
-       teardown script is missing, it is simply not executed.  If one of the
-       standard input, output, or error files is missing, it is treated as if
-       it were empty.  If the exit code file is missing, it is treated as if
-       it specified an exit code of zero.
-
-       The shell scripts may use the following environment variables:
-
-       DATADIR
-	      a temporary directory where files may be created by the test
-
-       TESTNAME
-	      name of the current test (will be empty for setup-once and tear‐
-	      down-once)
-
-       SRCDIR directory from which cmdtest was launched
-
-OPTIONS
-       -c, --command=COMMAND
-	      ignored for backwards compatibility
-
-       --generate-manpage=TEMPLATE
-	      SUPPRESSHELP
-
-       -h, --help
-	      show this help message and exit
-
-       -k, --keep
-	      keep temporary data on failure
-
-       --no-keep
-
-
-       --no-timings
-
-
-       --output=FILE
-	      write output to FILE, instead of standard output
-
-       -t, --test=TEST
-	      run only TEST (can be given many times)
-
-       --timings
-	      report how long each test takes
-
-       --version
-	      show program's version number and exit
-
-   Configuration files and settings
-       --config=FILE
-	      add FILE to config files
-
-       --dump-config
-	      write out the entire current configuration
-
-       --dump-setting-names
-	      SUPPRESSHELP
-
-       --help-all
-	      show all options
-
-       --list-config-files
-	      SUPPRESSHELP
-
-       --no-default-configs
-	      clear list of configuration files to read
-
-   Logging
-       --log=FILE
-	      write log entries to FILE (default is to not write log files at
-	      all); use "syslog" to log to system log, or "none" to disable
-	      logging
-
-       --log-keep=N
-	      keep last N logs (10)
-
-       --log-level=LEVEL
-	      log at LEVEL, one of debug, info, warning, error, critical, fa‐
-	      tal (default: debug)
-
-       --log-max=SIZE
-	      rotate logs larger than SIZE, zero for never (default: 0)
-
-       --log-mode=MODE
-	      set permissions of new log files to MODE (octal; default 0600)
-
-   Peformance
-       --dump-memory-profile=METHOD
-	      make memory profiling dumps using METHOD, which is one of: none,
-	      simple, meliae, or heapy (default: simple)
-
-       --memory-dump-interval=SECONDS
-	      make memory profiling dumps at least SECONDS apart
-
-EXAMPLE
-       To test that the echo(1) command outputs the expected string, create a
-       file called echo-tests/hello.script containing the following content:
-

(Diff truncated)
Move cachedir manpage to code.liw.fi
diff --git a/cachedir.mdwn b/cachedir.mdwn
index d6b7c04..82348b7 100644
--- a/cachedir.mdwn
+++ b/cachedir.mdwn
@@ -6,6 +6,6 @@ according to the <http://www.bford.info/cachedir/> specification.
 
 * [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cachedir/tree/README)
 * [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cachedir/tree/NEWS)
-* [[manual page|cachedir.1.txt]]
+* [manual page](http://code.liw.fi/cachedir/cachedir.1.txt)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cachedir/>
 * Git clone: `git://git.liw.fi/cachedir/`
diff --git a/cachedir/cachedir.1.txt b/cachedir/cachedir.1.txt
deleted file mode 100644
index 01abad2..0000000
--- a/cachedir/cachedir.1.txt
+++ /dev/null
@@ -1,102 +0,0 @@
-CACHEDIR(1)							   CACHEDIR(1)
-
-
-
-NAME
-       cachedir - tag/untag/find cache directories
-
-SYNOPSIS
-       cachedir [--config=FILE] [--dump-config] [--dump-memory-profile=METHOD]
-       [--dump-setting-names]  [--generate-manpage=TEMPLATE]   [-h]   [--help]
-       [--help-all]    [--list-config-files]	[--log=FILE]	[--log-keep=N]
-       [--log-level=LEVEL]	   [--log-max=SIZE]	     [--log-mode=MODE]
-       [--memory-dump-interval=SECONDS] [--no-default-configs] [--output=FILE]
-       [--version]
-
-       cachedir [options] help
-       cachedir [options] help-all
-
-DESCRIPTION
-       cachedir tags directories as cache directories, or remotes  such  tags,
-       or  finds  tagged  directories.	A cache directory tag is a file called
-       CACHEDIR.TAG with a specific content.  See the specification referenced
-       from the "SEE ALSO" section for details.
-
-OPTIONS
-       --generate-manpage=TEMPLATE
-	      SUPPRESSHELP
-
-       -h, --help
-	      show this help message and exit
-
-       --output=FILE
-	      write output to FILE, instead of standard output
-
-       --version
-	      show program's version number and exit
-
-   Configuration files and settings
-       --config=FILE
-	      add FILE to config files
-
-       --dump-config
-	      write out the entire current configuration
-
-       --dump-setting-names
-	      SUPPRESSHELP
-
-       --help-all
-	      show all options
-
-       --list-config-files
-	      SUPPRESSHELP
-
-       --no-default-configs
-	      clear list of configuration files to read
-
-   Logging
-       --log=FILE
-	      write  log entries to FILE (default is to not write log files at
-	      all); use "syslog" to log to system log, or  "none"  to  disable
-	      logging
-
-       --log-keep=N
-	      keep last N logs (10)
-
-       --log-level=LEVEL
-	      log  at LEVEL, one of debug, info, warning, error, critical, fa-
-	      tal (default: debug)
-
-       --log-max=SIZE
-	      rotate logs larger than SIZE, zero for never (default: 0)
-
-       --log-mode=MODE
-	      set permissions of new log files to MODE (octal; default 0600)
-
-   Peformance
-       --dump-memory-profile=METHOD
-	      make memory profiling dumps using METHOD, which is one of: none,
-	      simple, meliae, or heapy (default: simple)
-
-       --memory-dump-interval=SECONDS
-	      make memory profiling dumps at least SECONDS apart
-
-EXAMPLE
-       To tag a directory as a cache directory:
-
-	      cachedir tag $HOME/.cache
-
-       To remove a cache directory tag:
-
-	      cachedir untag $HOME/.cache
-
-       To find all cache directories below your home directory:
-
-	      cachedir find $HOME
-
-SEE ALSO
-       http://www.bford.info/cachedir/
-
-
-
-								   CACHEDIR(1)

Add title to extrautils page
diff --git a/extrautils.mdwn b/extrautils.mdwn
index 67138d1..1d167f0 100644
--- a/extrautils.mdwn
+++ b/extrautils.mdwn
@@ -1,3 +1,4 @@
+[[!meta title="extrautils - extra utilities for Unix systems"]]
 [[!tag program]]
 
 # Extra utilities for Unix

Move cliapp(5) to code.liw.fi
diff --git a/cliapp.mdwn b/cliapp.mdwn
index a454239..73ccb1a 100644
--- a/cliapp.mdwn
+++ b/cliapp.mdwn
@@ -10,8 +10,8 @@ compatible ways.
 
 * [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cliapp/tree/README)
 * [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cliapp/tree/NEWS)
+* [cliapp(5) manual page](http://code.liw.fi/cliapp/cliapp.5.txt)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cliapp/>
 * Git clone: `git://git.liw.fi/cliapp/`
-* [[cliapp(5) manual page|cliapp.5.txt]]
 * [API documentation](http://code.liw.fi/cliapp/docs/)
 * [[Bugs]]
diff --git a/cliapp/cliapp.5.txt b/cliapp/cliapp.5.txt
deleted file mode 100644
index 9644ba7..0000000
--- a/cliapp/cliapp.5.txt
+++ /dev/null
@@ -1,155 +0,0 @@
-CLIAPP(5)		      File Formats Manual		     CLIAPP(5)
-
-
-
-NAME
-       cliapp  -  config  file	and option conventions for Python command line
-       framework
-
-DESCRIPTION
-       cliapp is a Python  programming	framework  for	writing  command  line
-       applications   for  Unix-like  operating  systems.   This  manual  page
-       describes the conventions for  configuration  files  and  command  line
-       parsing provided by cliapp.
-
-       Configuration  file  variables  and command line options are handled by
-       cliapp under a uniform abstraction: every setting is available both  in
-       configuration  files  and  command  line options.  There are a few set‐
-       tings, provided by the framework itself, which are  only  available  on
-       the command line.  For example, --help outputs a short help text, list‐
-       ing all the available options, and --dump-config outputs a list of cur‐
-       rent configuration settings.
-
-       Command	line parsing follows GNU conventions: short options start with
-       a single dash, long options with two dashes, and options  may  be  used
-       anywhere  on the command line.  The order of options versus non-options
-       does not matter.  The exception is some of the options provided by  the
-       framework,  which  are executed immediately when found, and may be pre‐
-       vent the rest of the options from being parsed.	(--dump-config is  one
-       of  these,  so  use it at the end of the command line only.)  Use -- on
-       the command line to signal the end of options: no arguments after  that
-       are considered to be option.
-
-       Some  settings  may have aliases, which can be only a single character,
-       and in that case they're parsed as single-character option names.
-
-       Some applications have subcommands, which means	that  the  first  non-
-       option  argument  is  used to tell the application what to do.  This is
-       similar to what many version control systems do, for example CVS,  svn,
-       bzr, and git.  Options are global, and are not specific to subcommands.
-       Thus, --foo means the same thing,  regardless  of  what	subcommand  is
-       being used.
-
-   Configuration files
-       Configuration  files  use INI file syntax.  All the settings are in the
-       [config] section.  Other sections are allowed, but  it  is  up  to  the
-       application to give meaning to them.
-
-       Multiple  configuration	files  may  be read.  Settings from later ones
-       override settings from earlier ones.  Options  override	settings  from
-       the configuration files.
-
-   String list settings
-       Some settings may be a list of values (each value being a string).  For
-       example, there might be a setting for patterns to search for, and  mul‐
-       tiple patterns are allowed.  On the command line, that happens by using
-       the option multiple times.  In the configuration file, all  values  are
-       given  on one line, separated by commas.  This is a non-standard exten‐
-       sion to the INI file syntax.  There is no way to escape commas.
-
-       Example:
-
-	      [config]
-	      pattern = foo, bar, foobar
-
-   Boolean (true/false or on/off or yes/no) settings
-       When a setting can be either on or off, it's called a Boolean  setting.
-       Such  settings  are turned off by default, and turned on if used on the
-       command line.  In a configuration file, they need to be set to a value:
-       if  the	value is one of yes, on, true, or the number 1, the setting is
-       turned on.  Any other value means it is turned off.
-
-	      [config]
-	      verbose = true
-	      attack-kittens = no
-
-       This turns the verbose setting on, but does not launch attack kittens.
-
-       For every boolean setting, two command line options are added.  If  the
-       setting	is  called foo, the option --foo will turn the setting on, and
-       --no-foo will turn it off.  The negation is only usable on the  command
-       line:  its  purpose  is to allow the command line to override a setting
-       from the configuration file.
-
-   Logging and log files
-       Programs using cliapp automatically support several options for config‐
-       uring  the  Python  logging  module.  See the --help output for options
-       starting with log for details.  Logging can happen to  a  file  or  the
-       system log.  Log files can be rotated automatically based on size.
-
-       The  --trace  option enables additional debug logging, which is usually
-       only useful for programmers.  The option configures the tracing library
-       for Python, by Lars Wirzenius, which allows logging values of variables
-       and other debug information in a way that is very lightweight when  the
-       tracing	is  turned  off.   The	option specifies for which source code
-       files to turn on tracing.  The actual logging happens  via  the	normal
-       Python logging facilities, at the debug level.
-
-   Python profiling support
-       You  can  run  the  application under the Python profiler (cProfile) by
-       setting an environment variable.  The name of the variable is  FOO_PRO‐
-       FILE,  where  FOO is the name of the program, as set by the application
-       code or determined by cliapp automatically.  The value of the  environ‐
-       ment variable is the name of the file to which the resulting profile is
-       to be written.
-
-   Manual page generation
-       cliapp can generate parts of a manual page: the	SYNOPSIS  and  OPTIONS
-       sections.   It fills these in automatically based on the subcommand and
-       settings that a	program  supports.   Use  the  --generate-manpage=FILE
-       option,	which  is added automatically by cliapp.  The FILE is a manual
-       page marked up using the -man macros  for  troff(1).   It  should  have
-       empty SYNOPSIS and OPTIONS sections, and cliapp will fill them in.  The
-       output it to the standard output.
-
-       For example:
-
-	      foo --generate-manpage=foo.1.in > foo.1
-
-       You would keep the source code for the manual page in foo.1.in and have
-       your Makefile produce foo.1 as shown above.
-
-   Subcommands
-       cliapp  provides  a way for the application to have subcommands, in the
-       style of git(1), for example.  If the application is called  foo,  then
-       it  can have subcommands such as foo search, and foo print.  The appli‐
-       cation gets to define the name and meaning of  each  subcommand.   How‐
-       ever,  all  settings  (options and configuration files) are global, and
-       can be used with all subcommands.  It is up  to	each  subcommand  what
-       settings it obeys.
-
-       If  there  are any subcommands, cliapp automatically adds the help sub‐
-       command.  It allows you to get the help text for a specific  subommand:
-       foo help print, for example.
-
-FILES
-       cliapp reads a list of configuration files at startup, on behalf of the
-       application.  The name of the application is included in the name.   In
-       the filenames below, the application name is progname.
-
-       /etc/progname.conf
-	      Global configuration file.
-
-       /etc/progname/*.conf
-	      More global configuration files.	These are read in ASCII sorted
-	      order.
-
-       ~/.progname.conf
-	      Per-user configuration file.
-
-       ~/.config/progname/*.conf
-	      More per-user configuration files.  Again, ASCII sorted order.
-
-
-
-								     CLIAPP(5)

Remove now-obsolete Obnam release checklist
diff --git a/obnam/release.mdwn b/obnam/release.mdwn
deleted file mode 100644
index 75a4725..0000000
--- a/obnam/release.mdwn
+++ /dev/null
@@ -1,19 +0,0 @@
-[[!meta title="Making an Obnam release"]]
-
-Follow my [generic release checklist](http://liw.fi/release/),
-with the following notes:
-
-* Automatic tests (see also [[README]] section "Hacking"): 
-  - `make -s clean all check network-tests`
-* Bug tracker is using Ikiwiki, at
-  <http://liw.fi/obnam/bugs/>.
-* Announcements:
-  * blog, using tag `obnam`
-  * Obnam mailing list
-* Copy `NEWS` and `README` and formatted manpage to `liw.fi/obnam`.
-* Push updated wiki to server.
-* Run benchmark on the release version.
-
-As a special consideration, note that the 
-[B-tree library](http://liw.fi/btree/) Obnam uses may also need to
-be released at the same time.

Update my release checklist
diff --git a/release.mdwn b/release.mdwn
index 5bed040..e51bb4f 100644
--- a/release.mdwn
+++ b/release.mdwn
@@ -1,26 +1,19 @@
 [[!meta title="Software release checklist"]]
 [[!tag checklist]]
 
-1. Run full test suite.
-1. Prepare README, NEWS, setup.py, debian/changelog, version numbers (in
-   all places), and other files for release. Commit. Push.
-1. Run
-   `jenkinstool --config jenkinstool-real.conf run-jobs liw-real.conf $project`
-   to make sure things work.
-1. Tag the project with the version number.
-1. Run
-   `jenkinstool --config jenkinstool-real.conf run-jobs liw-real.conf $project`
-   to create release artifacts.
-1. Download release artifacts for all architectures.
-1. Run `debsign` and upload to `code.liw.fi` and, if appropriate, to Debian.
-1. Copy `NEWS`, `README`, examples, other relevant files to the project
-   home page.
-1. Upload to pypi, if relevant. (Under review: is pypi worth it?)
-  - `# python setup.py register`
+I used to have a long, detailed manual checklist here for making a
+release. Most of it has been replaced by using a CI system ([[ick]]).
+What remains here are the manual steps:
+
+1. Prepare README, NEWS, setup.py, debian/changelog for the release.
+1. Tag release: `git -sam "Release version x.y" foo-x.y`
+1. Run ick. This runs tests, builds release packages, and uploads them
+   to [[code.liw.fi|code]] and Debian, as needed.
 1. Announce on the relevant forums.
   - my blog
-  - a dedicated announcement mailing list
+  - the announcement mailing list, if any
   - identi.ca
+  - twitter
   
 On version numbers
 ------------------

Fix broken links
diff --git a/larch.mdwn b/larch.mdwn
index 3b45354..dda00d1 100644
--- a/larch.mdwn
+++ b/larch.mdwn
@@ -44,8 +44,8 @@ are your best hope.
 
 **Contributions are welcome.** Every level of contribution is most
 appreciated: bug reports, spelling and grammar fixes, code patches,
-questions on how to get started, etc. See [[README]] for information
-on how to modify the code. And if anything's unclear, ask!
+questions on how to get started, etc. See the README (link below) for
+information on how to modify the code. And if anything's unclear, ask!
 
 Status: in production use. The on-disk file format is not expected
 to change anymore.
diff --git a/seivot.mdwn b/seivot.mdwn
index d73b2a5..20713d7 100644
--- a/seivot.mdwn
+++ b/seivot.mdwn
@@ -14,8 +14,6 @@ It is licensed under the GPL, version 3 or later.
 
 See also:
 
-* [[README]]
-* [[NEWS]]
 * [[Bugs]]
 
 Downloads:

Add list of broken links
diff --git a/admin.mdwn b/admin.mdwn
new file mode 100644
index 0000000..5153b80
--- /dev/null
+++ b/admin.mdwn
@@ -0,0 +1,5 @@
+[[!meta title="wiki admin stuff"]]
+
+# Broken internal links
+
+[[!brokenlinks  pages="* and !recentchanges"]]

Remove obsolete copies of README, NEWS for all programs
diff --git a/cachedir/NEWS.mdwn b/cachedir/NEWS.mdwn
deleted file mode 100644
index 94cf506..0000000
--- a/cachedir/NEWS.mdwn
+++ /dev/null
@@ -1,13 +0,0 @@
-cachedir NEWS
-============
-
-Version 1.1, released 2013-03-15
---------------------------------
-
-* Test suite fixes.
-
-Version 1.0, released 2012-10-13
---------------------------------
-
-* First release.
-
diff --git a/cachedir/README.mdwn b/cachedir/README.mdwn
deleted file mode 100644
index b6cfe91..0000000
--- a/cachedir/README.mdwn
+++ /dev/null
@@ -1,24 +0,0 @@
-The cachedir cache directory tagging utility
-============================================
-
-cachedir is a tiny utility for tagging directories as cache directories,
-according to the <http://www.bford.info/cachedir/> specification.
-
-Legalese
---------
-
-Copyright 2012, 2013  Lars Wirzenius
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
diff --git a/cliapp/NEWS.mdwn b/cliapp/NEWS.mdwn
deleted file mode 100644
index 1890f7b..0000000
--- a/cliapp/NEWS.mdwn
+++ /dev/null
@@ -1,507 +0,0 @@
-NEWS for cliapp
-===============
-
-Version 1.20150829
-------------------
-
-Important, backwards incompatible bug fixes:
-
-* Jan Gerber fixed string list option handling. Command line options
-  no longer parse values by commas, so that `--foo=bar,foobar` results
-  in a single value `bar,foobar`, instead of two values (`bar` and
-  `foobar`). Also, in configuration files, values may be quoted with
-  double quotes.
-
-Bug fixes:
-
-* Memory use profiling with Meliae was fixed.
-
-New features:
-
-* Richard Ipsum added the `cliapp.Application.get_subcommand_usage`
-  method to return a short usage text for a subcommand. This allows
-  better error message.
-
-Version 1.20150701
-------------------
-
-* Lars Wirzenius added the `ssh_options` keyword argument to
-  `cliapp.ssh_runcmd` to allow adding command line options to the ssh
-  program.
-
-* Lars Wirzenius added the `remote_cwd` keyword argument to
-  `cliapp.ssh_runcmd` to allow the caller to easily change to a
-  directory on the server.
-
-* Support for `heapy` memory profile has been dropped. It's not
-  packaged for Debian, and is rarely available anywhere.
-
-
-Version 1.20150305
-------------------
-
-* Richard Ipsum added callbacks to `cliapp.runcmd` for handling
-  captured stdout/stderr output from the pipeline. This allows, for
-  example, progress reporting during a long-running command.
-
-* Richard Maw and Richard Ipsum fixed `cliapp.runcmd` to close file
-  descriptors correctly, to make `cliapp.runcmd(['cat', '/dev/zero'],
-  ['false'])` work correctly. Previously, the pipeline would never
-  finish, but now it does, because closing an unnecessary file
-  descriptor in the parent results in `SIGPIPE` being sent to the
-  `cat` process once `false` terminates.
-
-* Richard Maw changed `cliapp.runcmd` so that the stderr of all
-  commands in the pipeline are collected, when stderr is set to
-  `subprocess.PIPE`.
-
-Version 1.20140719
-------------------
-
-* The way logging is set up has been split into smaller methods, to
-  allow overriding better. See `setup_logging_handler_for_file`,
-  `setup_logging_formatter_for_file`, and
-  `setup_logging_formatter_for_syslog`.
-
-* Plugins no longer need to define a `disable` method: the default
-  implementation is now a no-op, instead of raising
-  `NotImplementedError`.
-
-Bug fixes:
-
-* When getting help for a subcommand, cliapp would crash saying
-  `get_help_text_formatter` couldn't be found. This has been fixed.
-
-Version 1.20140315
-------------------
-
-* Portability patch to disable VmRSS reporting on non-Linux platforms.
-  The code assumed that /proc/self/status exists, but that's only true
-  on Linux. Patch from Itamar Turner-Trauring.
-
-* `cliapp` now logs the current working directory, uid, effective uid,
-  gid, and effective gid at startup.
-
-* `cliapp` (`Settings.load_configs`) now reports an unknown
-  variable in a configuration file with a nice error message, rather
-  than a stack trace.
-
-* A new method, `cliapp.Application.get_subcommand_help_formatter`
-  allows overriding how the full help text for a subcommand is to be
-  formatted. This can be useful for allowing help texts be marked up
-  in, say, Markdown.
-
-* The `cliapp.Settings.require` method now accepts many setting names,
-  and check for all of them. Patch by Stephen Judd.
-
-Version 1.20130808
-------------------
-
-* Bug fix to cliapp.runcmd pipeline handling: the pipeline now returns
-  failure if any of the processes fails, rather than only the last one.
-  Found and reported by Richard Maw.
-* Fix a problem in the pipeline code in runcmd. Reported and fix provided
-  by Richard Maw.
-
-Version 1.20130613
-------------------
-
-* cliapp(5) now mentions subcommands and the automatic subcommand
-  "help".
-* `ssh_runcmd` now has the `tty` keyword argument to enable ssh
-  allocation of pseudo-TTYs. Patch from Jannis Pohlmann.
-* The `help` subcommand now writes a useful error message, instead of
-  a stack trace, if given an unknown subcommand. Reported by Rob Taylor.
-
-Version 1.20130424
-------------------
-
-* The API documentation has been split into more than one page.
-
-Bug fixes:
-
-* `cliapp.runcmd` no longer dies from the `SIGWINCH` signal.
-
-Version 1.20130313
-------------------
-
-* Add `cliapp.Application.compute_setting_values` method. This allows
-  the application to have settings with values that are computed after
-  configuration files and the command line are parsed.
-* Cliapp now logs the Python version at startup, to aid debugging.
-* `cliapp.runcmd` now logs much less during execution of a command. The
-  verbose logging was useful while developing pipeline support, but has
-  now not been useful for months.
-* More default settings and options have an option group now, making
-  `--help` output prettier.
-* The `--help` output and the output of the `help` subcommand now only
-  list summaries for subcommands. The full documentation for a subcommand
-  can be seen by giving the name of the subcommand to `help`.
-* Logging setup is now more overrideable. The `setup_logging` method
-  calls `setup_logging_handler_for_syslog`,
-  `setup_logging_handler_for_syslog`, or
-  `setup_logging_handler_to_file`, and the last one calls
-  `setup_logging_format` and `setup_logging_timestamp` to create the
-  format strings for messages and timestamps. This allows applications

(Diff truncated)
Update titles for some program pages
diff --git a/cmdtest.mdwn b/cmdtest.mdwn
index c232057..cbcd1fc 100644
--- a/cmdtest.mdwn
+++ b/cmdtest.mdwn
@@ -1,4 +1,4 @@
-[[!meta title="cmdtest"]]
+[[!meta title="cmdtest - black box testing of Unix command line tools"]]
 [[!tag program]]
 
 `cmdtest` black box tests Unix command line tools.
diff --git a/coverage-test-runner.mdwn b/coverage-test-runner.mdwn
index 33ef9ff..b60f20c 100644
--- a/coverage-test-runner.mdwn
+++ b/coverage-test-runner.mdwn
@@ -1,4 +1,4 @@
-[[!meta title="CoverageTestRunner"]]
+[[!meta title="CoverageTestRunner - run unit tests with coverage measurement"]]
 [[!tag program]]
 
 **CoverageTestRunner** is a [Python](http://www.python.org/) module for
diff --git a/distix.mdwn b/distix.mdwn
index 9e32c4a..005b99c 100644
--- a/distix.mdwn
+++ b/distix.mdwn
@@ -1,4 +1,4 @@
-[[!meta title="distix"]]
+[[!meta title="distix - distributed ticketing system"]]
 [[!tag program]]
 
 Distix will be a distributed ticketing system. It is very much a
diff --git a/vmdebootstrap.mdwn b/vmdebootstrap.mdwn
index 148173a..400b436 100644
--- a/vmdebootstrap.mdwn
+++ b/vmdebootstrap.mdwn
@@ -1,3 +1,4 @@
+[[!meta title="vmdebootstrap - create Debian disk images for real and virtual machines"]]
 [[!tag program]]
 
 `debootstrap` installs a basic Debian system into a directory, for use with

Update links for ttystatus
diff --git a/ttystatus.mdwn b/ttystatus.mdwn
index 4db96fb..8a508a8 100644
--- a/ttystatus.mdwn
+++ b/ttystatus.mdwn
@@ -22,17 +22,10 @@ incompatible ways.
 
 See also:
 
-* [[README]]
-* [[NEWS]]
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ttystatus/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ttystatus/tree/NEWS)
+* [example.py](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ttystatus/tree/example.py)
 * [API documentation](http://code.liw.fi/ttystatus/docs/)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ttystatus/>
+* Git clone: `git://git.liw.fi/ttystatus/`
 * [[Bug tracking page|ttystatus/bugs]]
-
-Downloads:
-
-* [[Using stuff on code.liw.fi|code]]
-* Version control:
-  * <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ttystatus/>
-  * `git clone git://git.liw.fi/ttystatus`
-* Tarball and Debian packages: 
-  <http://code.liw.fi/debian/pool/main/p/python-ttystatus/>
-

Update links for tracing
diff --git a/tracing.mdwn b/tracing.mdwn
index 5d71947..4577117 100644
--- a/tracing.mdwn
+++ b/tracing.mdwn
@@ -20,10 +20,10 @@ Status: in production use.
 
 See also:
 
-* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/tracing/tree/README)
-* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/tracing/tree/NEWS)
-* [example.py](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/tracing/tree/example.py)
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/python-tracing/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/python-tracing/tree/NEWS)
+* [example.py](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/python-tracing/tree/example.py)
 * [Documentation](http://code.liw.fi/python-tracing/docs/)
-* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/tracing/>
-* Git clone: `git://git.liw.fi/tracing/`
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/python-tracing/>
+* Git clone: `git://git.liw.fi/python-tracing/`
 * [[Bugs]]

Update links for tracing
diff --git a/tracing.mdwn b/tracing.mdwn
index 90fd103..5d71947 100644
--- a/tracing.mdwn
+++ b/tracing.mdwn
@@ -20,14 +20,10 @@ Status: in production use.
 
 See also:
 
-* [[NEWS]]
-* [[README]]
-* [[example.py]]
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/tracing/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/tracing/tree/NEWS)
+* [example.py](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/tracing/tree/example.py)
 * [Documentation](http://code.liw.fi/python-tracing/docs/)
-* [[Using stuff on code.liw.fi|code]]
-* Version control:
-  * <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/python-tracing/>
-  * `git clone git://git.liw.fi/python-tracing`
-* Tarball and Debian packages: 
-  <http://code.liw.fi/debian/pool/main/p/python-tracing/>
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/tracing/>
+* Git clone: `git://git.liw.fi/tracing/`
 * [[Bugs]]

Update links for summain
diff --git a/summain.mdwn b/summain.mdwn
index cdb07da..3705407 100644
--- a/summain.mdwn
+++ b/summain.mdwn
@@ -8,17 +8,9 @@ generated for a directory tree at different points in time and compared
 
 See also:
 
-* [[README]]
-* [[NEWS]]
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/summain/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/summain/tree/NEWS)
 * [[manpage|summain.1.txt]]
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/summain/>
+* Git clone: `git://git.liw.fi/summain/`
 * [[Bugs]]
-
-Downloads:
-
-* [[Using stuff on code.liw.fi|code]]
-* Version control:
-  * <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/summain/>
-  * `git clone git://git.liw.fi/summain`
-* Tarball and Debian packages: 
-  <http://code.liw.fi/debian/pool/main/s/summain/>
-

Update links for larch
diff --git a/larch.mdwn b/larch.mdwn
index 077746b..3b45354 100644
--- a/larch.mdwn
+++ b/larch.mdwn
@@ -50,16 +50,12 @@ on how to modify the code. And if anything's unclear, ask!
 Status: in production use. The on-disk file format is not expected
 to change anymore.
 
-* [[README]] (updated at release time)
-* [[NEWS]] (updated at release time)
-* [[example.py]] (an example program)
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/larch/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/larch/tree/NEWS)
+* [example.py](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/larch/tree/example.py)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/larch/>
+* Git clone: `git://git.liw.fi/larch/`
 * [API documentation](http://code.liw.fi/larch/docs/)
-* [[Using stuff on code.liw.fi|code]]
-* Version control:
-  * <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/larch/>
-  * `git clone git://git.liw.fi/larch`
-* Release tarballs and Debian packages:
-  <http://code.liw.fi/debian/pool/main/p/python-larch/>
 * [[Benchmark results|benchmarks]]
 * [[Release checklist|larch/release]]
 * [[Bug tracking page|larch/bugs]]

Update links for ick
diff --git a/ick.mdwn b/ick.mdwn
index 943b699..c6eee9f 100644
--- a/ick.mdwn
+++ b/ick.mdwn
@@ -4,7 +4,7 @@
 ick is a command line continous integration system I wrote for my own
 needs. You probably want something else instead.
 
-* Version control:
-    - <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ick/>
-    - `git clone git://git.liw.fi/ick`
-* [Using stuff on code.liw.fi](http://liw.fi/code/)
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ick/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ick/tree/NEWS)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ick/>
+* Git clone: `git://git.liw.fi/ick/`

Update links for genbackupdata
diff --git a/genbackupdata.mdwn b/genbackupdata.mdwn
index c0642c8..9220fe8 100644
--- a/genbackupdata.mdwn
+++ b/genbackupdata.mdwn
@@ -3,17 +3,9 @@
 
 genbackupdata is a program to generate test data for backup software testing.
 
-* [[README]]
-* [[NEWS]]
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/genbackupdata/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/genbackupdata/tree/NEWS)
 * [[manpage|genbackupdata.1.txt]]
-* [Using stuff on code.liw.fi](http://liw.fi/code/)
-* Version control:
-  * <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/genbackupdata/>
-  * `git clone git://git.liw.fi/genbackupdata`
-* Tarball and Debian packages: 
-  <http://code.liw.fi/debian/pool/main/g/genbackupdata/>
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/genbackupdata/>
+* Git clone: `git://git.liw.fi/genbackupdata/`
 * [[Bugs]]
-
-See also:
-
-* [seivot](http://liw.fi/seivot/)

Update links for extrautils
diff --git a/extrautils.mdwn b/extrautils.mdwn
index dc0aafe..67138d1 100644
--- a/extrautils.mdwn
+++ b/extrautils.mdwn
@@ -10,10 +10,8 @@ that it needs to be free software and needs to work.
 
 See also:
 
-* [[Using stuff on code.liw.fi|code]]
-* Version control:
-  * <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/extrautils/>
-  * `git clone git://git.liw.fi/extrautils`
-* Tarball and Debian packages: 
-  <http://code.liw.fi/debian/pool/main/e/extrautils/>
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/extrautils/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/extrautils/tree/NEWS)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/extrautils/>
+* Git clone: `git://git.liw.fi/extrautils/`
 * [[Bugs]]

Update links for dupfiles
diff --git a/dupfiles.mdwn b/dupfiles.mdwn
index 72e9c79..94fcf22 100644
--- a/dupfiles.mdwn
+++ b/dupfiles.mdwn
@@ -20,7 +20,6 @@ not. Worked for me, but please be careful. Patches most welcome.
 
 See also:
 
-* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/dupfiles/tree/README)
 * [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/dupfiles/tree/NEWS)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/dupfiles/>
 * Git clone: `git://git.liw.fi/dupfiles/`

Update links for dupfiles
diff --git a/dupfiles.mdwn b/dupfiles.mdwn
index 6e5209b..72e9c79 100644
--- a/dupfiles.mdwn
+++ b/dupfiles.mdwn
@@ -20,16 +20,12 @@ not. Worked for me, but please be careful. Patches most welcome.
 
 See also:
 
-* [[NEWS]]
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/dupfiles/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/dupfiles/tree/NEWS)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/dupfiles/>
+* Git clone: `git://git.liw.fi/dupfiles/`
 * [[Bugs]]
 
-Downloads:
-
-* [[Using stuff on code.liw.fi|code]]
-* Version control: `bzr branch http://code.liw.fi/dupfiles/bzr/trunk/`
-* Tarball and Debian packages: 
-  <http://code.liw.fi/debian/pool/main/d/dupfiles/>
-
 Benchmark results
 -----------------
 
@@ -44,8 +40,6 @@ the source tree). I made a copy of my laptop home directory to a server
 
 Times are in seconds. hardlink is the clear winner in this case.
 
-I'd be interested in results from other data sets.
-
 Other tools
 ------------
 

Update links for drop-caches
diff --git a/drop-caches.mdwn b/drop-caches.mdwn
index 5d25c31..731c4e4 100644
--- a/drop-caches.mdwn
+++ b/drop-caches.mdwn
@@ -15,6 +15,5 @@ So I wrote a tiny utility for this.
 See also:
 
 * [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/drop-caches/tree/README)
-* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/drop-caches/tree/NEWS)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/drop-caches/>
 * Git clone: `git://git.liw.fi/drop-caches/`

Update links for drop-caches
diff --git a/drop-caches.mdwn b/drop-caches.mdwn
index 083dece..5d25c31 100644
--- a/drop-caches.mdwn
+++ b/drop-caches.mdwn
@@ -14,5 +14,7 @@ So I wrote a tiny utility for this.
 
 See also:
 
-* [[README]]
-* [Git](http://git.gitano.org.uk/personal/liw/drop-caches.git/)
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/drop-caches/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/drop-caches/tree/NEWS)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/drop-caches/>
+* Git clone: `git://git.liw.fi/drop-caches/`

Update links for distix
diff --git a/distix.mdwn b/distix.mdwn
index d8a59a4..9e32c4a 100644
--- a/distix.mdwn
+++ b/distix.mdwn
@@ -8,9 +8,9 @@ develop distix.
 You want the [[performance-art]] subpage for now.
 
 * [this will become the home page](http://distix.eu)
-* [[README]]
-* [[NEWS]] (release notes)
-* [[TUTORIAL]]
-* [git](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/distix/)
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/distix/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/distix/tree/NEWS)
+* [TUTORIAL](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/distix/tree/TUTORIAL)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/distix/>
+* Git clone: `git://git.liw.fi/distix/`
 * [distix bugs](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/distix-bugs/)
-* Debian packages on [[code.liw.fi|code]].

Update links for desktop-cronish
diff --git a/desktop-cronish.mdwn b/desktop-cronish.mdwn
index 2f7f8c1..9a6c464 100644
--- a/desktop-cronish.mdwn
+++ b/desktop-cronish.mdwn
@@ -12,7 +12,7 @@ configured to get the IMAP password from the GNOME Keyring.
 
 See also:
 
-* [[README]]
-* Version control:
-  * <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/desktop-cronish/>
-  * `git clone git://git.liw.fi/desktop-cronish`
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/desktop-cronish/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/desktop-cronish/tree/NEWS)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/desktop-cronish/>
+* Git clone: `git://git.liw.fi/desktop-cronish/`

Update links for coverage-test-runner
diff --git a/coverage-test-runner.mdwn b/coverage-test-runner.mdwn
index dec86a5..33ef9ff 100644
--- a/coverage-test-runner.mdwn
+++ b/coverage-test-runner.mdwn
@@ -30,15 +30,10 @@ CoverageTestRunner is licensed under the
 [[GNU_General_Public_License,_version_3|licenses/gpl3]], or (at your
 option) any later version.
 
-# Downloads
+# Links
 
-* [[README]]
-* [[NEWS]]
-* [[Using stuff on code.liw.fi|code]]
-
-# Development stuff
-
-* Version control:
-  * <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/coverage-test-runner/>
-  * `git clone git://git.liw.fi/coverage-test-runner`
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/coverage-test-runner/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/coverage-test-runner/tree/NEWS)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/coverage-test-runner/>
+* Git clone: `git://git.liw.fi/coverage-test-runner/`
 * [[Bugs]]

Update links for copyright-statement-lint
diff --git a/copyright-statement-lint.mdwn b/copyright-statement-lint.mdwn
index 797643e..b4900c0 100644
--- a/copyright-statement-lint.mdwn
+++ b/copyright-statement-lint.mdwn
@@ -7,7 +7,6 @@ statement, or the latest commit year is not included in the years of
 any of the statements you do have.
 
 * [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/copyright-statement-lint/tree/README)
-* [README.yarn](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/copyright-statement-lint/tree/README.yarn)
 * [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/copyright-statement-lint/tree/NEWS)
 * Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/copyright-statement-lint/>
 * Git clone: `git://git.liw.fi/copyright-statement-lint/`

Update links for copyright-statement-lint
diff --git a/cmdtest.mdwn b/cmdtest.mdwn
index 88c0791..c232057 100644
--- a/cmdtest.mdwn
+++ b/cmdtest.mdwn
@@ -14,5 +14,3 @@ If not, it reports a problem, and shows the differences.
 * [[cmdtest manpage|cmdtest.1.txt]]
 * [[yarn manpage|yarn.1.txt]]
 * [[Bugs]]
-
-
diff --git a/copyright-statement-lint.mdwn b/copyright-statement-lint.mdwn
index 69d8a13..797643e 100644
--- a/copyright-statement-lint.mdwn
+++ b/copyright-statement-lint.mdwn
@@ -6,12 +6,8 @@ git, for copyright statements, and whinges if you don't have a
 statement, or the latest commit year is not included in the years of
 any of the statements you do have.
 
-* [[README]] (updated at release time)
-* [[NEWS]] (updated at release time)
-* [[Using stuff on code.liw.fi|code]]
-* Version control:
-  * <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/copyright-statement-lint/>
-  * `git clone git://git.liw.fi/copyright-statement-lint`
-* Release tarballs and Debian packages:
-  <http://code.liw.fi/debian/pool/main/c/copyright-statement-lint/>
-* Copyright license: GNU GPL3 or later.
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/copyright-statement-lint/tree/README)
+* [README.yarn](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/copyright-statement-lint/tree/README.yarn)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/copyright-statement-lint/tree/NEWS)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/copyright-statement-lint/>
+* Git clone: `git://git.liw.fi/copyright-statement-lint/`

Update links for cmdtest
diff --git a/cmdtest.mdwn b/cmdtest.mdwn
index 3507ee4..88c0791 100644
--- a/cmdtest.mdwn
+++ b/cmdtest.mdwn
@@ -6,18 +6,13 @@ Roughly, it is given a command line and input files, and the expected output,
 and it verifies that the command line produces the expected output.
 If not, it reports a problem, and shows the differences.
 
-* [[README]] for cmdtest
-* [[README.yarn]] for yarn
-* [[NEWS]]
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cmdtest/tree/README)
+* [README.yarn](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cmdtest/tree/README.yarn)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cmdtest/tree/NEWS)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cmdtest/>
+* Git clone: `git://git.liw.fi/cmdtest/`
 * [[cmdtest manpage|cmdtest.1.txt]]
 * [[yarn manpage|yarn.1.txt]]
+* [[Bugs]]
 
-See also:
 
-* [[Using stuff on code.liw.fi|code]]
-* Version control:
-  * <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cmdtest/>
-  * `git clone git://git.liw.fi/cmdtest`
-* Tarball and Debian packages: 
-  <http://code.liw.fi/debian/pool/main/c/cmdtest/>
-* [[Bugs]]

Update links for cliapp
diff --git a/cliapp.mdwn b/cliapp.mdwn
index c35ab39..a454239 100644
--- a/cliapp.mdwn
+++ b/cliapp.mdwn
@@ -8,16 +8,10 @@ parsing the command line for options, and iterating over input files.
 Status: in production. New features will happen in backwards
 compatible ways.
 
-* [[README]]
-* [[NEWS]]
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cliapp/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cliapp/tree/NEWS)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cliapp/>
+* Git clone: `git://git.liw.fi/cliapp/`
 * [[cliapp(5) manual page|cliapp.5.txt]]
-* Examples: [[example.py]], [[example2.py]], [[example3.py]],
-  [[example4.py]], [[example5.py]].
 * [API documentation](http://code.liw.fi/cliapp/docs/)
-* [[Using stuff on code.liw.fi|code]]
-* Version control:
-  * <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cliapp/>
-  * `git clone git://git.liw.fi/cliapp`
-* Tarball and Debian packages: 
-  <http://code.liw.fi/debian/pool/main/p/python-cliapp/>
 * [[Bugs]]
diff --git a/cliapp/example.py b/cliapp/example.py
deleted file mode 100644
index fe282be..0000000
--- a/cliapp/example.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2011  Lars Wirzenius
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-
-'''Example for cliapp framework.
-
-This implements an fgrep-like utility.
-
-'''
-
-
-import cliapp
-import logging
-
-
-class ExampleApp(cliapp.Application):
-
-    '''A little fgrep-like tool.'''
-
-    def add_settings(self):
-        self.settings.string_list(
-            ['pattern', 'e'],
-            'search for regular expression PATTERN',
-            metavar='REGEXP')
-
-        self.settings.boolean(
-            ['dummy'],
-            'this setting is ignored',
-            group='Test Group')
-
-        self.settings.string(
-            ['yoyo'],
-            'yoyo',
-            group=cliapp.config_group_name)
-
-        self.settings.string(
-            ['nono'],
-            'nono',
-            default=None)
-
-    # We override process_inputs to be able to do something after the last
-    # input line.
-    def process_inputs(self, args):
-        self.matches = 0
-        cliapp.Application.process_inputs(self, args)
-        self.output.write('There were %s matches.\n' % self.matches)
-
-    def process_input_line(self, name, line):
-        logging.debug('processing %s:%s', name, self.lineno)
-        for pattern in self.settings['pattern']:
-            if pattern in line:
-                self.output.write('%s:%s: %s' % (name, self.lineno, line))
-                self.matches += 1
-                logging.debug('Match: %s line %d', name, self.lineno)
-
-
-app = ExampleApp(version='0.1.2')
-app.settings.config_files = ['example.conf']
-app.run()
-
diff --git a/cliapp/example2.py b/cliapp/example2.py
deleted file mode 100644
index 972e880..0000000
--- a/cliapp/example2.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (C) 2011  Lars Wirzenius
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-
-'''Example for cliapp framework.
-
-Greet or insult people.
-
-'''
-
-
-import cliapp
-
-
-class ExampleApp(cliapp.Application):
-
-    cmd_synopsis = {
-        'greet': '[USER]...',
-        'insult': '[USER]...',
-    }
-
-    def cmd_greet(self, args):
-        '''Greet the user.
-
-        The user is treated to a a courteus,
-        but terse form of greeting.
-
-        '''
-        for arg in args:
-            self.output.write('greetings, %s\n' % arg)
-
-    def cmd_insult(self, args):
-        '''Insult the user.
-
-        Sometimes, though rarely, it happens that a user is really a bit of
-        a prat, and needs to be told off. This is the command for that.
-
-        '''
-        for arg in args:
-            self.output.write('you suck, %s\n' % arg)
-
-
-app = ExampleApp(
-    version='0.1.2',
-    description='''
-Greet the user.
-Or possibly insult them. User's choice.
-''',
-    epilog='''
-This is the epilog.
-
-I hope you like it.
-''')
-
-app.run()
-
diff --git a/cliapp/example3.py b/cliapp/example3.py
deleted file mode 100644
index 163231d..0000000
--- a/cliapp/example3.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2012  Lars Wirzenius
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

(Diff truncated)
Update links for clab
diff --git a/clab.mdwn b/clab.mdwn
index 4b721d1..5cba5fe 100644
--- a/clab.mdwn
+++ b/clab.mdwn
@@ -4,7 +4,7 @@
 clab is a small command line address book application I wrote after
 I got disappointed by abook losing data.
 
-* Version control:
-    - <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/clab/>
-    - `git clone git://git.liw.fi/clab`
-* [Using stuff on code.liw.fi](http://liw.fi/code/)
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/clab/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/clab/tree/NEWS)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/clab/>
+* Git clone: `git://git.liw.fi/clab/`

Update links for cachedir
diff --git a/cachedir.mdwn b/cachedir.mdwn
index 39aa7a6..d6b7c04 100644
--- a/cachedir.mdwn
+++ b/cachedir.mdwn
@@ -4,11 +4,8 @@
 cachedir is a tiny utility for tagging directories as cache directories,
 according to the <http://www.bford.info/cachedir/> specification.
 
-* [[README]]
-* [[NEWS]]
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cachedir/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cachedir/tree/NEWS)
 * [[manual page|cachedir.1.txt]]
-* [Using stuff on code.liw.fi](http://liw.fi/code/)
-* Version control:
-    - <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cachedir/>
-    - `git clone git://git.liw.fi/cachedir`
-
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/cachedir/>
+* Git clone: `git://git.liw.fi/cachedir/`

Add git links to bumper
diff --git a/bumper.mdwn b/bumper.mdwn
index ee2d0c0..279cd9a 100644
--- a/bumper.mdwn
+++ b/bumper.mdwn
@@ -4,4 +4,7 @@
 I use Bumper to update the version number and create a git release tag
 when making a software release.
 
-* Git: <git://git.liw.fi/bumper/>
+* [README](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/bumper/tree/README)
+* [NEWS](http://git.liw.fi/cgi-bin/cgit/cgit.cgi/bumper/tree/NEWS)
+* Git browse: <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/bumper/>
+* Git clone: `git://git.liw.fi/bumper/`

Add link to HTTP statuses
diff --git a/links.mdwn b/links.mdwn
index a924c3c..b20e104 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -12,6 +12,7 @@ incarnation of that web page.
 [Valuutat](http://www.suomenpankki.fi/en/tilastot/valuuttakurssit/Pages/tilastot_valuuttakurssit_valuuttakurssit_today_en.aspx)
 [Sanakirja](http://www.sanakirja.org/)
 [Kierrätys](http://www.kierratys.info/)
+[HTTP status codes](http://www.restapitutorial.com/httpstatuscodes.html)
 
 **Books:**
 [OpenLibrary](http://openlibrary.org)

Update genbackupdata NEWS, manpage
diff --git a/genbackupdata/NEWS.mdwn b/genbackupdata/NEWS.mdwn
index 882cb8a..dc75dea 100644
--- a/genbackupdata/NEWS.mdwn
+++ b/genbackupdata/NEWS.mdwn
@@ -1,6 +1,19 @@
 NEWS for genbackupdata
 ======================
 
+Version 1.9, released 2015-17-18
+--------------------------------
+
+* Fix progress reporting to always output something, even if the
+  program ran very fast. Previously, there would just be an empty
+  line.
+
+Version 1.8, released 2015-07-14
+--------------------------------
+
+* Change how binary data gets generated. It is now much less repetetive.
+  Suggested by Rob Kendrick.
+
 Version 1.7, released 2012-09-29
 --------------------------------
 
diff --git a/genbackupdata/genbackupdata.1.txt b/genbackupdata/genbackupdata.1.txt
index 2004536..3ef0ac9 100644
--- a/genbackupdata/genbackupdata.1.txt
+++ b/genbackupdata/genbackupdata.1.txt
@@ -1,4 +1,4 @@
-GENBACKUPDATA(1)					      GENBACKUPDATA(1)
+GENBACKUPDATA(1)	    General Commands Manual	      GENBACKUPDATA(1)
 
 
 
@@ -6,22 +6,22 @@ NAME
        genbackupdata - generate backup test data
 
 SYNOPSIS
-       genbackupdata	 [--chunk-size=SIZE]	 [--config=FILE]     [-c=SIZE]
-       [--create=SIZE]		   [--depth=DEPTH]	       [--dump-config]
-       [--dump-memory-profile=METHOD]			[--dump-setting-names]
-       [--file-size=SIZE]    [--generate-manpage=TEMPLATE]    [-h]    [--help]
-       [--list-config-files]  [--log=FILE]  [--log-keep=N] [--log-level=LEVEL]
+       genbackupdata   [--chunk-size=SIZE]   [--config=FILE]   [--dump-config]
+       [--dump-setting-names]  [--generate-manpage=TEMPLATE]   [-h]   [--help]
+       [--help-all]  [--list-config-files]  [--version] [--no-default-configs]
+       [-cSIZE] [--create=SIZE] [--depth=DEPTH] [--dump-memory-profile=METHOD]
+       [--file-size=SIZE]   [--log=FILE]   [--log-keep=N]  [--log-level=LEVEL]
        [--log-max=SIZE]       [--log-mode=MODE]        [--max-files=MAX-FILES]
-       [--no-default-configs]	 [--output=FILE]    [--quiet]	 [--seed=SEED]
-       [--version] [FILE]...
+       [--memory-dump-interval=SECONDS] [--output=FILE] [--quiet] [--no-quiet]
+       [--seed=SEED] [FILE]...
 
 DESCRIPTION
-       genbackupdata generates test data sets for performance testing of back-
-       up  software.  It creates a directory tree filled with files of differ-
+       genbackupdata generates test data sets for performance testing of back‐
+       up  software.  It creates a directory tree filled with files of differ‐
        ent sizes.  The total size and the distribution of sizes between  small
-       and  big are configurable.  The program can also modify an existing di-
-       rectory tree by creating new files, and deleting, renaming, or  modify-
-       ing existing files.  This can be used to generate test data for succes-
+       and  big are configurable.  The program can also modify an existing di‐
+       rectory tree by creating new files, and deleting, renaming, or  modify‐
+       ing existing files.  This can be used to generate test data for succes‐
        sive generations of backups.
 
        The program is deterministic: with a given set  of  parameters  (and  a
@@ -36,62 +36,84 @@ DESCRIPTION
        be set, as can the sizes of the respective file types.
 
        Files  and  directories are named "fileXXXX" or "dirXXXX", where "XXXX"
-       is a successive integer, separate successions for  files  and  directo-
-       ries.   There  is an upper limit to how many files a directory may con-
+       is a successive integer, separate successions for  files  and  directo‐
+       ries.   There  is an upper limit to how many files a directory may con‐
        tain.  After the file limit is reached, a new sub-directory is created.
        The first set of files go into the root directory of the test set.
 
        You  have  to  give one of the options --create, --delete, --rename, or
        --modify for the program to do anything.  You can, however,  give  more
        than  one of them, if DIR already exists.  (Giving the same option more
-       than once means that only the last instance is counted.)  (DIR) is cre-
+       than once means that only the last instance is counted.)  (DIR) is cre‐
        ated if it doesn't exist already.
 
 OPTIONS
        --chunk-size=SIZE
-	      generate data in chunks of this size (default: 16384)
-
-       --config=FILE
-	      add FILE to config files
+	      generate data in chunks of this size
 
        -c, --create=SIZE
 	      how much data to create (default: 0)
 
        --depth=DEPTH
-	      depth of directory tree (default: 3)
-
-       --dump-config
-	      write out the entire current configuration
-
-       --dump-memory-profile=METHOD
-	      make memory profiling dumps using METHOD, which is one of: none,
-	      simple, meliae, or heapy (default: simple)
-
-       --dump-setting-names
-	      write out all names of settings and quit
+	      depth of directory tree
 
        --file-size=SIZE
-	      size of one file (default: 16384)
+	      size of one file
 
        --generate-manpage=TEMPLATE
-	      fill in manual page TEMPLATE
+	      SUPPRESSHELP
 
        -h, --help
 	      show this help message and exit
 
+       --max-files=MAX-FILES
+	      max files/dirs per dir
+
+       --output=FILE
+	      write output to FILE, instead of standard output
+
+       --quiet
+	      do not report progress
+
+       --no-quiet
+	      opposite of --quiet
+
+       --seed=SEED
+	      seed for random number generator
+
+       --version
+	      show program's version number and exit
+
+   Configuration files and settings
+       --config=FILE
+	      add FILE to config files
+
+       --dump-config
+	      write out the entire current configuration
+
+       --dump-setting-names
+	      SUPPRESSHELP
+
+       --help-all
+	      show all options
+
        --list-config-files
-	      list all possible config files
+	      SUPPRESSHELP
 
+       --no-default-configs
+	      clear list of configuration files to read
+
+   Logging
        --log=FILE
-	      write log entries to FILE (default is to not write log files  at
-	      all);  use  "syslog"  to log to system log, or "none" to disable
-	      logging
+	      write  log entries to FILE (default is to not write log files at
+	      all); use "syslog" to log to system log, "stderr" to log to  the
+	      standard error output, or "none" to disable logging
 
        --log-keep=N
 	      keep last N logs (10)
 
        --log-level=LEVEL
-	      log at LEVEL, one of debug, info, warning, error, critical,  fa-
+	      log  at LEVEL, one of debug, info, warning, error, critical, fa‐
 	      tal (default: debug)
 
        --log-max=SIZE
@@ -100,23 +122,13 @@ OPTIONS
        --log-mode=MODE
 	      set permissions of new log files to MODE (octal; default 0600)
 
-       --max-files=MAX-FILES
-	      max files/dirs per dir (default: 128)
-
-       --no-default-configs
-	      clear list of configuration files to read
-
-       --output=FILE
-	      write output to FILE, instead of standard output
-
-       --quiet
-	      do not report progress
-
-       --seed=SEED
-	      seed for random number generator (default: 0)
+   Peformance
+       --dump-memory-profile=METHOD
+	      make memory profiling dumps using METHOD, which is one of: none,

(Diff truncated)
Close old wishlist bugs
diff --git a/dupfiles/bugs/cmdtest.mdwn b/dupfiles/bugs/cmdtest.mdwn
index 5ab0c15..7abe8d3 100644
--- a/dupfiles/bugs/cmdtest.mdwn
+++ b/dupfiles/bugs/cmdtest.mdwn
@@ -1,3 +1,5 @@
 dupfiles should use yarn for black box testing. It should also have
 test for `--no-act` for hardlinking, removals, and that when removing, it
 keeps a copy in the last directory given on the command line. --liw
+
+[[done]] (old wishlist bug, nothing happening for years) -- liw
diff --git a/dupfiles/bugs/progress-hardlinking.mdwn b/dupfiles/bugs/progress-hardlinking.mdwn
index 43bd292..9f4bbc0 100644
--- a/dupfiles/bugs/progress-hardlinking.mdwn
+++ b/dupfiles/bugs/progress-hardlinking.mdwn
@@ -1 +1,3 @@
 `--progress` doesn't do anything for hardlinking. --liw
+
+[[done]] (old wishlist bug, nothing happening for years) --liw

Close bug
diff --git a/cliapp/bugs/manpage-should-include-subcommand-descriptions.mdwn b/cliapp/bugs/manpage-should-include-subcommand-descriptions.mdwn
index 0d3d548..c431368 100644
--- a/cliapp/bugs/manpage-should-include-subcommand-descriptions.mdwn
+++ b/cliapp/bugs/manpage-should-include-subcommand-descriptions.mdwn
@@ -1,2 +1,5 @@
 The documentation for subcommands is already in the code, so including
-it in the manpage would be good.
+it in the manpage would be good. --liw
+
+[[done]] because this is a wishlist bug that's been open for years without
+happening. --liw

Close bug
diff --git a/cliapp/bugs/better-list-support-on-config-files.mdwn b/cliapp/bugs/better-list-support-on-config-files.mdwn
index 265c78f..d99b7f6 100644
--- a/cliapp/bugs/better-list-support-on-config-files.mdwn
+++ b/cliapp/bugs/better-list-support-on-config-files.mdwn
@@ -4,3 +4,5 @@ config file format might be nice: yaml? --liw
 
 YAML would be nice, but adds a dependency outside of stdlib.
 That's not good. --liw
+
+[[done]] by support YAML. --liw

Close bug
diff --git a/cliapp/bugs/help-does-not-include-list-config-option.mdwn b/cliapp/bugs/help-does-not-include-list-config-option.mdwn
index 132be45..e100f2b 100644
--- a/cliapp/bugs/help-does-not-include-list-config-option.mdwn
+++ b/cliapp/bugs/help-does-not-include-list-config-option.mdwn
@@ -1,2 +1,4 @@
 `foo --help` doesn't seem to include `--list-config` and maybe other
 command-line-only options that cliapp itself adds. --liw
+
+[[done]] --liw

Add link to thehuone
diff --git a/links.mdwn b/links.mdwn
index b0c33b4..a924c3c 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -80,6 +80,7 @@ incarnation of that web page.
 [Slaters](http://www.slaters.co.uk/)
 [Specsavers](http://www.specsavers.co.uk/)
 [Algerian Coffee](http://www.algcoffee.co.uk)
+[Théhuone](http://www.thehuone.com/fi/)
 
 **Organizations:**
 [EFFI](http://www.effi.org/)

Add home page for bumper
diff --git a/bumper.mdwn b/bumper.mdwn
new file mode 100644
index 0000000..ee2d0c0
--- /dev/null
+++ b/bumper.mdwn
@@ -0,0 +1,7 @@
+[[!meta title="bumper: Update version numbers and make release tag"]]
+[[!tag program]]
+
+I use Bumper to update the version number and create a git release tag
+when making a software release.
+
+* Git: <git://git.liw.fi/bumper/>

Tweak links
diff --git a/links.mdwn b/links.mdwn
index 3f4cc1c..b0c33b4 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -11,8 +11,7 @@ incarnation of that web page.
 **Frequent:**
 [Valuutat](http://www.suomenpankki.fi/en/tilastot/valuuttakurssit/Pages/tilastot_valuuttakurssit_valuuttakurssit_today_en.aspx)
 [Sanakirja](http://www.sanakirja.org/)
-[Aukiolot](http://www.pty.fi/kaupan-toiminta/aukioloajat/kaupan-aukioloajat-2015/)
-[Liikenne-tilanne](http://liikennetilanne.liikennevirasto.fi/)
+[Kierrätys](http://www.kierratys.info/)
 
 **Books:**
 [OpenLibrary](http://openlibrary.org)

Add link to Cimos
diff --git a/links.mdwn b/links.mdwn
index 5fb91c0..3f4cc1c 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -64,6 +64,7 @@ incarnation of that web page.
 [verkkokauppa](http://www.verkkokauppa.com)
 [jimms](http://www.jimms.fi)
 [TKV](http://www.tkvfinland.fi/)
+[Cimos](http://www.cimos.fi/)
 
 **Approved content sources:**
 [Amazon UK](http://www.amazon.co.uk/)

Fix typo (thanks, iDunno)
diff --git a/vmdebootstrap.mdwn b/vmdebootstrap.mdwn
index 593bf8a..148173a 100644
--- a/vmdebootstrap.mdwn
+++ b/vmdebootstrap.mdwn
@@ -4,7 +4,7 @@
 `chroot`(8). `vmdeboostrap` is a wrapper around it to install Debian into a disk
 image, which can be used with a virtual machine (such as KVM).
 
-`vmdebootstrap` is now mainteind by Neil Williams.
+`vmdebootstrap` is now maintained by Neil Williams.
 
 * <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/vmdebootstrap>
 * `git clone git://git.liw.fi/vmdebootstrap`

creating tag page tag/idea
diff --git a/tag/idea.mdwn b/tag/idea.mdwn
new file mode 100644
index 0000000..d7f58c7
--- /dev/null
+++ b/tag/idea.mdwn
@@ -0,0 +1,4 @@
+[[!meta title="pages tagged idea"]]
+
+[[!inline pages="tagged(idea)" actions="no" archive="yes"
+feedshow=10]]

Add idea fstabcmd
diff --git a/ideas/fstabcmd.mdwn b/ideas/fstabcmd.mdwn
new file mode 100644
index 0000000..94c8560
--- /dev/null
+++ b/ideas/fstabcmd.mdwn
@@ -0,0 +1,35 @@
+[[!meta title="fatab command"]]
+[[!tag idea]]
+
+Sometimes I wish for a command to edit `/etc/fstab`. Something like
+the follow.
+
+Add a new entry:
+
+    fstab add -s LABEL=scratch -w /scratch -o rw -o user_xattr -t btrfs
+
+Add an entry based on an existing mount (get device, other settings,
+from the mount point):
+
+    fstab add -m /scratch
+
+Remove an entry:
+
+    fstab remove /scratch
+
+Modify an existing entry:
+
+    fstab edit /scratch -o +foo -o -bar -t auto
+
+Check that `/etc/fstab` looks OK:
+
+    fstab check
+
+Edit `/etc/fstab` in an editor and, afterwards, check that it looks OK
+(c.f. `visudo`).
+
+    fstab vi
+
+Re-format `/etc/fstab` so that it looks pretty:
+
+    fstab prettify

Update cmdtest NEWS
diff --git a/cmdtest/NEWS.mdwn b/cmdtest/NEWS.mdwn
index 2220611..a1d18cc 100644
--- a/cmdtest/NEWS.mdwn
+++ b/cmdtest/NEWS.mdwn
@@ -3,6 +3,24 @@ NEWS for cmdtest
 
 This file summarizes changes between releases of cmdtest.
 
+Version 0.18, released 2015-11-06
+---------------------------------
+
+* Code blocks that are examples are now supported.
+
+* Snapshot directories are now created only when `--snapshot` is used.
+
+Version 0.17, released 2015-09-21
+---------------------------------
+
+* Yarn now flushes outputs (stdout, stderr) whenever it writes
+  anything. This should avoid some problems with programs that capture
+  yarn output, such as CI systems, and get the timings differently
+  from what would happen on a terminal.
+
+* The `--require-assumptions` option has been added to tell Yarn to
+  treat failing ASSUMPTIONS steps as errors.
+
 Version 0.16, released 2015-06-30
 ---------------------------------
 

Add link to distix.eu
diff --git a/distix.mdwn b/distix.mdwn
index 1a211f1..d8a59a4 100644
--- a/distix.mdwn
+++ b/distix.mdwn
@@ -7,6 +7,7 @@ develop distix.
 
 You want the [[performance-art]] subpage for now.
 
+* [this will become the home page](http://distix.eu)
 * [[README]]
 * [[NEWS]] (release notes)
 * [[TUTORIAL]]

Add sources.list line for jessie
diff --git a/code.mdwn b/code.mdwn
index bb077c8..41110f8 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -26,6 +26,7 @@ You're welcome to use the repository. To do so, add **one of** the
 following to your `sources.list` file:
 
     deb http://code.liw.fi/debian wheezy main
+    deb http://code.liw.fi/debian jessie main
     deb http://code.liw.fi/debian unstable main
 
 The [PGP key that is used to sign the Release 

Remove obsolete links
diff --git a/links.mdwn b/links.mdwn
index 10513d2..5fb91c0 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -132,10 +132,6 @@ incarnation of that web page.
 [Calumet](http://www.calumetphoto.co.uk/)
 [Camera Price Buster UK](http://www.camerapricebuster.co.uk/)
 
-**Offices:**
-[Ring Table](http://www.tmproductions.com/RingTable/)
-[Tame cables](http://www.pcworld.com/article/92925/stepbystep_eight_tips_to_tame_cables.html)
-
 **Travel/transport:**
 [International power and plugs](http://www.dbicorporation.com/internat/intpower.htm)
 [IEC connector](http://en.wikipedia.org/wiki/IEC_connector)

Update cliapp NEWS
diff --git a/cliapp/NEWS.mdwn b/cliapp/NEWS.mdwn
index 7066dee..1890f7b 100644
--- a/cliapp/NEWS.mdwn
+++ b/cliapp/NEWS.mdwn
@@ -1,6 +1,27 @@
 NEWS for cliapp
 ===============
 
+Version 1.20150829
+------------------
+
+Important, backwards incompatible bug fixes:
+
+* Jan Gerber fixed string list option handling. Command line options
+  no longer parse values by commas, so that `--foo=bar,foobar` results
+  in a single value `bar,foobar`, instead of two values (`bar` and
+  `foobar`). Also, in configuration files, values may be quoted with
+  double quotes.
+
+Bug fixes:
+
+* Memory use profiling with Meliae was fixed.
+
+New features:
+
+* Richard Ipsum added the `cliapp.Application.get_subcommand_usage`
+  method to return a short usage text for a subcommand. This allows
+  better error message.
+
 Version 1.20150701
 ------------------
 

Close bug
diff --git a/larch/bugs/remove_range-slow.mdwn b/larch/bugs/remove_range-slow.mdwn
index 546ae66..7c8623e 100644
--- a/larch/bugs/remove_range-slow.mdwn
+++ b/larch/bugs/remove_range-slow.mdwn
@@ -1,3 +1,6 @@
 The `remove_range` method is implemented in a simplistic manner,
 and is fairly slow. It should be optimized, but my attempts to
 do so have resulted in bugs so far. --liw
+
+[[done]] Larch is in serious-bug-fixes-only mode. This isn't serious enough.
+--liw

Close bug
diff --git a/larch/bugs/insert-remove-code-too-tricky.mdwn b/larch/bugs/insert-remove-code-too-tricky.mdwn
index fde35d7..5b8c220 100644
--- a/larch/bugs/insert-remove-code-too-tricky.mdwn
+++ b/larch/bugs/insert-remove-code-too-tricky.mdwn
@@ -1,3 +1,5 @@
 The B-tree insert and remove code should be simplified so it is not
 so tricky (and, hence, fragile if there's a need to change).  --liw
 
+[[done]] Larch is in serious-bug-fixes-only mode. This isn't serious enough.
+--liw

Close bug
diff --git a/larch/bugs/vivify-unnecessary-round-trip.mdwn b/larch/bugs/vivify-unnecessary-round-trip.mdwn
index dc6b474..06067e5 100644
--- a/larch/bugs/vivify-unnecessary-round-trip.mdwn
+++ b/larch/bugs/vivify-unnecessary-round-trip.mdwn
@@ -1,2 +1,5 @@
 It seems `_vivify` does a "test, then do" thing, instead of doing a
 "do, handle error" thing. This costs an extra round trip. --liw
+
+[[done]] Larch is in serious-bug-fixes-only mode. This isn't serious enough.
+--liw

Close bug
diff --git a/larch/bugs/does-not-remove-empty-dirs-from-journal.mdwn b/larch/bugs/does-not-remove-empty-dirs-from-journal.mdwn
index adceae2..706b398 100644
--- a/larch/bugs/does-not-remove-empty-dirs-from-journal.mdwn
+++ b/larch/bugs/does-not-remove-empty-dirs-from-journal.mdwn
@@ -1,2 +1,5 @@
 When committing the journal, empty dirs in the `new` subdir should
 be removed, so they do not accumulate indefinitely. --liw
+
+[[done]] Larch is in serious-bug-fixes-only mode. This isn't serious enough.
+--liw

Close bug
diff --git a/larch/bugs/use-listdir2-in-journal.mdwn b/larch/bugs/use-listdir2-in-journal.mdwn
index 5c3750b..c85ef6e 100644
--- a/larch/bugs/use-listdir2-in-journal.mdwn
+++ b/larch/bugs/use-listdir2-in-journal.mdwn
@@ -2,3 +2,6 @@ For performance, larch's journal should use listdir2 so it does not
 need to stat everything manually. sftp provides the stat results
 with a single roundtrip for everything in the directory. However,
 this needs to be done carefully, for backwards compatbility. --liw
+
+[[done]] larch is in maintenance-only mode and I won't be fixing this
+unless it's crucial. --liw

Close bug
diff --git a/genbackupdata/bugs/too-compressible.mdwn b/genbackupdata/bugs/too-compressible.mdwn
index 24d8083..e83cda9 100644
--- a/genbackupdata/bugs/too-compressible.mdwn
+++ b/genbackupdata/bugs/too-compressible.mdwn
@@ -6,3 +6,7 @@ slow. --liw
 
 Check out http://bzr.rjek.com/public/arcfour for code that generates
 random data quickly. It's in C, which may be necessary. --liw
+
+---
+
+[[done]] --liw

Close bug
diff --git a/cliapp/bugs/app-or-user-specified-plugin-dirs.mdwn b/cliapp/bugs/app-or-user-specified-plugin-dirs.mdwn
index 690f083..ff3cccf 100644
--- a/cliapp/bugs/app-or-user-specified-plugin-dirs.mdwn
+++ b/cliapp/bugs/app-or-user-specified-plugin-dirs.mdwn
@@ -1,2 +1,4 @@
 Add to cliapp a way for app or user to add a list of directories to scan
 for plugins.
+
+[[done]] Another long-lived-nothing-happend wishlist bug. --liw

Close bug
diff --git a/cliapp/bugs/multiple-log-files.mdwn b/cliapp/bugs/multiple-log-files.mdwn
index 00c2b12..6dd3b81 100644
--- a/cliapp/bugs/multiple-log-files.mdwn
+++ b/cliapp/bugs/multiple-log-files.mdwn
@@ -1 +1,6 @@
 It would be nice to have multiple log files, at different levels.
+
+---
+
+[[done]] Another long-lived wishlist bug that has not happened.
+This can be done by doing things with the `logging` library directly. --liw

Close bugs
diff --git a/cliapp/bugs/runcmd-output-capture-callbacks.mdwn b/cliapp/bugs/runcmd-output-capture-callbacks.mdwn
index 8e67c0f..17b4153 100644
--- a/cliapp/bugs/runcmd-output-capture-callbacks.mdwn
+++ b/cliapp/bugs/runcmd-output-capture-callbacks.mdwn
@@ -2,3 +2,5 @@ It would be nice to be able to capture, in real time, the output from the comman
 cliapp.runcmd runs, via callbacks or otherwise. Ideally, such callbacks could
 also filter/modify the output: if nothing else, this could reduce the amount of
 data runcmd keeps in memory at once. --liw
+
+[[done]]
diff --git a/cliapp/bugs/whence-setting-value.mdwn b/cliapp/bugs/whence-setting-value.mdwn
index 5e0f5a4..2fb1a8c 100644
--- a/cliapp/bugs/whence-setting-value.mdwn
+++ b/cliapp/bugs/whence-setting-value.mdwn
@@ -3,3 +3,9 @@ of where the value of each setting comes from: default? option?
 from a config file? which config file? and line in that file?
 
 Suggested-By: Daniel Silverstone
+
+---
+
+This is a good idea, but it's been on the wishlist for years and nothing happens.
+I'll implement it when there's an acute need, and for that I don't need a bug
+open. [[done]] --liw

Remove obsolete cafepress links
diff --git a/index.mdwn b/index.mdwn
index e0291f0..0d45ca7 100644
--- a/index.mdwn
+++ b/index.mdwn
@@ -15,7 +15,6 @@ Hello. I am Lars Wirzenius. Welcome to my little corner of cyberspace.
 * [My blog](http://blog.liw.fi)
 * [[My CV|cv]]
 * [Getting Things Done for Hackers](http://gtdfh.branchable.com/)
-* [Trunktees T-shirts](http://www.cafepress.com/trunktees)
 * [Branchable](http://www.branchable.com/) where this site is hosted
 
 <hr />
diff --git a/t.mdwn b/t.mdwn
index e7a63fb..0109d20 100644
--- a/t.mdwn
+++ b/t.mdwn
@@ -1,9 +1,6 @@
 Welcome!
 
-* [T-shirts](http://www.cafepress.com/trunktees)
 * [Getting Things Done for Hackers](http://gtdfh.branchable.com/)
   is my e-book about personal productivity for people who spend a
   lot of time with their computers.
 * [[Obnam]] is my backup software.
-
-See the sidebar for more links.

Add ick home page
diff --git a/ick.mdwn b/ick.mdwn
new file mode 100644
index 0000000..943b699
--- /dev/null
+++ b/ick.mdwn
@@ -0,0 +1,10 @@
+[[!meta title="ick - continuous integration"]]
+[[!tag program]]
+
+ick is a command line continous integration system I wrote for my own
+needs. You probably want something else instead.
+
+* Version control:
+    - <http://git.liw.fi/cgi-bin/cgit/cgit.cgi/ick/>
+    - `git clone git://git.liw.fi/ick`
+* [Using stuff on code.liw.fi](http://liw.fi/code/)

Update cmdtest home page for new release
diff --git a/cmdtest/NEWS.mdwn b/cmdtest/NEWS.mdwn
index 340a5dc..2220611 100644
--- a/cmdtest/NEWS.mdwn
+++ b/cmdtest/NEWS.mdwn
@@ -3,6 +3,20 @@ NEWS for cmdtest
 
 This file summarizes changes between releases of cmdtest.
 
+Version 0.16, released 2015-06-30
+---------------------------------
+
+* Flush terminal status output whenever a new scenario or step is
+  started. This ensures the terminal isn't showing an earlier, very
+  fast step, when the actual current step is slow.
+
+Version 0.15, released 2015-06-29
+---------------------------------
+
+* Steps are indented when yarn is run in `--verbose` mode.
+
+* Failed scenarios are listed at the end of yarn output.
+
 Version 0.14, released 2015-03-05
 ---------------------------------
 

Update cliapp home page for new release
diff --git a/cliapp/NEWS.mdwn b/cliapp/NEWS.mdwn
index f600b9c..7066dee 100644
--- a/cliapp/NEWS.mdwn
+++ b/cliapp/NEWS.mdwn
@@ -1,6 +1,21 @@
 NEWS for cliapp
 ===============
 
+Version 1.20150701
+------------------
+
+* Lars Wirzenius added the `ssh_options` keyword argument to
+  `cliapp.ssh_runcmd` to allow adding command line options to the ssh
+  program.
+
+* Lars Wirzenius added the `remote_cwd` keyword argument to
+  `cliapp.ssh_runcmd` to allow the caller to easily change to a
+  directory on the server.
+
+* Support for `heapy` memory profile has been dropped. It's not
+  packaged for Debian, and is rarely available anywhere.
+
+
 Version 1.20150305
 ------------------
 
diff --git a/cliapp/example.py b/cliapp/example.py
index 14a56db..fe282be 100644
--- a/cliapp/example.py
+++ b/cliapp/example.py
@@ -31,16 +31,25 @@ class ExampleApp(cliapp.Application):
     '''A little fgrep-like tool.'''
 
     def add_settings(self):
-        self.settings.string_list(['pattern', 'e'],
-                                  'search for regular expression PATTERN',
-                                   metavar='REGEXP')
-
-        self.settings.boolean(['dummy'], 'this setting is ignored',
-                              group='Test Group')
-
-        self.settings.string(['yoyo'], 'yoyo', group=cliapp.config_group_name)
-
-        self.settings.string(['nono'], 'nono', default=None)
+        self.settings.string_list(
+            ['pattern', 'e'],
+            'search for regular expression PATTERN',
+            metavar='REGEXP')
+
+        self.settings.boolean(
+            ['dummy'],
+            'this setting is ignored',
+            group='Test Group')
+
+        self.settings.string(
+            ['yoyo'],
+            'yoyo',
+            group=cliapp.config_group_name)
+
+        self.settings.string(
+            ['nono'],
+            'nono',
+            default=None)
 
     # We override process_inputs to be able to do something after the last
     # input line.
@@ -50,12 +59,12 @@ class ExampleApp(cliapp.Application):
         self.output.write('There were %s matches.\n' % self.matches)
 
     def process_input_line(self, name, line):
-        logging.debug('processing %s:%s' % (name, self.lineno))
+        logging.debug('processing %s:%s', name, self.lineno)
         for pattern in self.settings['pattern']:
             if pattern in line:
                 self.output.write('%s:%s: %s' % (name, self.lineno, line))
                 self.matches += 1
-                logging.debug('Match: %s line %d' % (name, self.lineno))
+                logging.debug('Match: %s line %d', name, self.lineno)
 
 
 app = ExampleApp(version='0.1.2')
diff --git a/cliapp/example2.py b/cliapp/example2.py
index 1f061b9..972e880 100644
--- a/cliapp/example2.py
+++ b/cliapp/example2.py
@@ -23,7 +23,6 @@ Greet or insult people.
 
 
 import cliapp
-import logging
 
 
 class ExampleApp(cliapp.Application):
@@ -54,14 +53,17 @@ class ExampleApp(cliapp.Application):
             self.output.write('you suck, %s\n' % arg)
 
 
-app = ExampleApp(version='0.1.2', description='''
+app = ExampleApp(
+    version='0.1.2',
+    description='''
 Greet the user.
 Or possibly insult them. User's choice.
 ''',
-epilog='''
+    epilog='''
 This is the epilog.
 
 I hope you like it.
 ''')
+
 app.run()
 
diff --git a/cliapp/example4.py b/cliapp/example4.py
index f500bbd..c6ba78f 100644
--- a/cliapp/example4.py
+++ b/cliapp/example4.py
@@ -16,7 +16,6 @@
 
 
 import cliapp
-import logging
 
 
 class ExampleApp(cliapp.Application):
diff --git a/cliapp/example5.py b/cliapp/example5.py
index 2e83bae..c6ab7b2 100644
--- a/cliapp/example5.py
+++ b/cliapp/example5.py
@@ -16,7 +16,6 @@
 
 
 import cliapp
-import logging
 
 
 class LoggerApp(cliapp.Application):

Remove broken links
diff --git a/links.mdwn b/links.mdwn
index 2a9c182..10513d2 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -91,7 +91,6 @@ incarnation of that web page.
 [K&amp;R2 answers](http://clc-wiki.net/wiki/K%26R2_solutions)
 [The C10K problem](http://www.kegel.com/c10k.html)
 [Portland Pattern Repository](http://c2.com/cgi/wiki)
-[Pentomino](http://yucs.org/~gnivasch/pentomino/)
 [Kuhn UTF-8 test](http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt)
 [Hsieh hash](http://www.azillionmonkeys.com/qed/hash.html)
 [rsync](http://www.samba.org/rsync/tech_report/)
@@ -119,7 +118,6 @@ incarnation of that web page.
 
 **General net:**
 [feed validator](http://feedvalidator.org/)
-[showmyip](http://www.showmyip.com/)
 [pagerank](http://www.prchecker.info/check_page_rank.php)
 [down?](http://downforeveryoneorjustme.com/)
 [Reply-To munging still harmful](http://woozle.org/~neale/papers/reply-to-still-harmful.html)

Add link to liikennetilanne
diff --git a/links.mdwn b/links.mdwn
index 0d8e4a9..2a9c182 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -12,6 +12,7 @@ incarnation of that web page.
 [Valuutat](http://www.suomenpankki.fi/en/tilastot/valuuttakurssit/Pages/tilastot_valuuttakurssit_valuuttakurssit_today_en.aspx)
 [Sanakirja](http://www.sanakirja.org/)
 [Aukiolot](http://www.pty.fi/kaupan-toiminta/aukioloajat/kaupan-aukioloajat-2015/)
+[Liikenne-tilanne](http://liikennetilanne.liikennevirasto.fi/)
 
 **Books:**
 [OpenLibrary](http://openlibrary.org)

Add link to Tuxedoe
diff --git a/links.mdwn b/links.mdwn
index 7ce2b8a..0d8e4a9 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -55,6 +55,7 @@ incarnation of that web page.
 [pcpartpicker](http://pcpartpicker.com/)
 [N40L](http://n40l.wikia.com/wiki/HP_MicroServer_N40L_Wiki)
 [Lenovo PSREF](http://lenovo.com/psref/)
+[Tuxedo](http://www.tuxedocomputers.com/)
 
 **Computer stores:**
 [crucial](http://www.crucial.com/uk/index.aspx)

Add note to idea
diff --git a/ideas/remote-executor.mdwn b/ideas/remote-executor.mdwn
index e918936..82e8adf 100644
--- a/ideas/remote-executor.mdwn
+++ b/ideas/remote-executor.mdwn
@@ -24,3 +24,6 @@ easier to handle in C.
 * Server sends a termination message when subprocess ends.
 * Client might send messages to do specific system calls (e.g., load
   average, statfs, etc).
+
+Possibly this should be stateless, or otherwise so that it's very easy
+to use from shell scripts that invoke ssh to run individual commands.

Add link to pcpartpicker
diff --git a/links.mdwn b/links.mdwn
index 410d631..7ce2b8a 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -52,6 +52,7 @@ incarnation of that web page.
 [luxio](http://www.rjek.com/bin/luxio/)
 
 **Hardware:**
+[pcpartpicker](http://pcpartpicker.com/)
 [N40L](http://n40l.wikia.com/wiki/HP_MicroServer_N40L_Wiki)
 [Lenovo PSREF](http://lenovo.com/psref/)
 

Remove dead link
diff --git a/links.mdwn b/links.mdwn
index fdc95f3..410d631 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -11,7 +11,6 @@ incarnation of that web page.
 **Frequent:**
 [Valuutat](http://www.suomenpankki.fi/en/tilastot/valuuttakurssit/Pages/tilastot_valuuttakurssit_valuuttakurssit_today_en.aspx)
 [Sanakirja](http://www.sanakirja.org/)
-[Pyhäpäivät](http://www.juhlapyhät.fi/viralliset-pyhapaivat-ja-vapaapaivat)
 [Aukiolot](http://www.pty.fi/kaupan-toiminta/aukioloajat/kaupan-aukioloajat-2015/)
 
 **Books:**

Add idea about remote executor
diff --git a/ideas/remote-executor.mdwn b/ideas/remote-executor.mdwn
new file mode 100644
index 0000000..e918936
--- /dev/null
+++ b/ideas/remote-executor.mdwn
@@ -0,0 +1,26 @@
+It's often necessary to run commands on a remote Unix host. For
+example, a CI system will run jobs on worker machines, or a system
+test might do that to test a server. This is reasonably easy to do by
+running a command at a time over an ssh connection. However, it might
+be nice to have an agent on the remote end. The agent should be
+written in portable C and have a minimal size, so that it can be run
+even on embedded devices. (Most CI systems have an agent like this,
+but they're usually written in Java or another language that makes
+things difficult.)
+
+The agent would read messages from its stdin, and write messages to
+its stdout. Messages are in some systematic, structured form, perahps
+soething like JSON or YAML, but maybe with less overhead and perhaps
+easier to handle in C.
+
+* Client would request executing processes.
+    - argv
+    - env
+    - redirections, pipelines
+* Server responds with messages to confirm start of process, and
+  sending its stdout, stderr output (without extra buffering).
+* Client can send messages with data to feed to the process' stdin.
+* Client can send control messages, to send signals.
+* Server sends a termination message when subprocess ends.
+* Client might send messages to do specific system calls (e.g., load
+  average, statfs, etc).

Remove now-unnecessary computer store links
diff --git a/links.mdwn b/links.mdwn
index 1d85eae..fdc95f3 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -57,17 +57,8 @@ incarnation of that web page.
 [Lenovo PSREF](http://lenovo.com/psref/)
 
 **Computer stores:**
-[ccl](http://www.cclonline.com/)
-[micro direct](http://www.microdirect.co.uk/Home/)
-[pc world](http://pcworld.co.uk/gbuk/index.html)
-[maplin](http://www.maplin.co.uk/)
-[plugs](http://www.plugcomputer.org/)
-[pcspecialist](http://pcspecialist.co.uk/)
 [crucial](http://www.crucial.com/uk/index.aspx)
-[aria](http://www.aria.co.uk/)
-[Cubieboard](http://linux-sunxi.org/Cubieboard)
 [Tier 1](http://www.tier1online.com/)
-[Span](http://www.span.com/)
 [verkkokauppa](http://www.verkkokauppa.com)
 [jimms](http://www.jimms.fi)
 [TKV](http://www.tkvfinland.fi/)

Remove people section in links
diff --git a/links.mdwn b/links.mdwn
index 7bc6117..1d85eae 100644
--- a/links.mdwn
+++ b/links.mdwn
@@ -56,10 +56,6 @@ incarnation of that web page.
 [N40L](http://n40l.wikia.com/wiki/HP_MicroServer_N40L_Wiki)
 [Lenovo PSREF](http://lenovo.com/psref/)
 
-**People:**
-[Arno Wirzenius](http://www.iki.fi/arno.w/)
-[Jukka Rajala](http://www.jukkar.com/)
-
 **Computer stores:**
 [ccl](http://www.cclonline.com/)
 [micro direct](http://www.microdirect.co.uk/Home/)