Posts about metaprocess

Getting things done after Getting Things Done

I first looked into Getting Things Done my first year out of university. Though I suppose having some sense of personal organization and time management would have been nice to have in the seventeen years of study prior, my new state as an employee sent me searching for something more than excuses and a general habit of procrastination.

I'm the kind of person who visits a bookstore just to hang out. (If I ever conquer my own commercialism I'll hopefully transform into a library patron.) It was at one of my many trips to the local Barnes & Noble that I saw a copy of David Allen's book. Though I had heard of the book before, but the simple cover, pleasing proportions, and unassuming title shone through my initial cynicism. I picked up paperback, and made short order.

Getting Things Done, by David Allen

Soon my life was awash in contexts… lists… habits… projects… actions. I had a little paper notebook that contained everything I needed to not have to remember; I had 43 folders in my desk and in my reader, and even more manilla in a box full of files; I had an other box full of "stuff" that kept the stuff out of sight; and I was trying (mostly failing) to have weekly reviews about what I had done, what I was doing, and what I needed to do next.

This actually worked pretty well. I spent less time worrying about forgetting things, because if I needed to remember it, I just wrote it down. I spent less time trying to spin up to productivity because I already had "next actions" for all of my "projects."

I even had an empty email inbox.

…but all of this new headroom gave me the freedom to notice seams between David Allen's proposed system and my own requirements. First was in the sense of contexts: though, in a corporate office, simple things like "@phone" or "@desk" or "@home" effectively partition a task space into appreciable chunks, I work in computers. The vast majority of my tasks are "@computer" or, at the very most, "@Internet." That doesn't do much to calm the mind when you're staring at a long to–do list.

I liked the ubiquity and tactility of paper, but the medium has its faults. Completed tasks clutter up the page, and to clear them you have to transcribe any remaining items to a new page. Reorganizing items into different contexts bring the same problem. There's no way to archive (let alone audit) task history without even more transcription, since tasks for different projects are physically intermingled. Most damningly, separating tasks from the notes that go with them is both a mental and physical context–switch that plagues every non-trivial task.

For its faults, GTD had actually taught me a lot of really good lessons:

  1. The brain is way better at thinking than remembering.
  2. The less you have to remember, the more you can think.
  3. The more you need to think, the less you want to think.
  4. Don't waste time making the same decision twice.
  5. Lists add a sense of progression to otherwise intangible work.
  6. There is too much to do to consider all at once.

All existing GTD software was powerless to placate a sysadmin's sensibilities. It's all point–and–clicky, high–friction, and, worst case, web-based. I did the only thing I could do: I moved all my lists to text files, added one project ("write command-line GTD software" and one action ("brainstorm requirements for GTD software").

That project didn't go so well; but it's ok, because since then I've migrated to Emacs Org-Mode.

The Org–Mode Unicorn

Rather than being a software environment that I had to re–factor my workflow into, Org–Mode provides a rich set of (extensible and seemingly–infinitely–configurable) functions to manipulate my text lists–cum–text–files as I see fit. All of that on top of a mature <strike>text editor</strike>lisp runtime (albeit one with which I had no experience).

First off, I configured Org–Mode with some familiar list item types:

(setq org-todo-keywords
      '((type "ACTION(a!)"            "|" "DONE(d!)")
        (type "PROJECT(p!)"           "|" "DONE(d!)")
        (type "WAITING(w!)"           "|" "DONE(d!)")
        (type "SOMEDAY(s)" "MAYBE(m)" "|")
        (type                         "|" "DELEGATED(g@)" "CANCELLED(x@)")))

…then configured some simple logging:

(setq org-log-into-drawer t)
(setq org-log-reschedule 'note)
(setq org-log-redeadline t)
(setq org-log-done 'time)

Suddenly my lists grew automatic logging in the form of the LOGBOOK drawer:

* PROJECT make a new first post on civilfritz
- State "PROJECT"    from ""           [2011-08-15 Mon 21:04]
** DONE figure out the post sorting problem
CLOSED: [2011-08-16 Tue 20:35]
- State "DONE"       from "PROJECT"    [2011-08-16 Tue 20:35]
- State "PROJECT"    from "ACTION"     [2011-08-16 Tue 08:04]
- State "ACTION"     from ""           [2011-08-15 Mon 22:31]
** ACTION write about getting things done after getting things done
SCHEDULED: <2011-08-16 Tue>
- State "ACTION"     from ""           [2011-08-16 Tue 21:09]

Of course, that's a lot of clutter, too; but that's just what's physically stored in the file. Org–Mode provides a flexible view of the outline. For example:

* PROJECT make a new first post on civilfritz
  * DONE figure out the post sorting problem...
  * ACTION write about getting things done after getting things done
    SCHEDULED: <2011-08-16 Tue>

That's much easier to look at. In Emacs, color is used to make the content even clearer.

As simple as these little bits of text are, the triviality of their automation means that they can be parsed by other parts of Org–Mode. Most notably, by the agenda.

(defun org-find-agenda-files ()
  (find-lisp-find-files "~/agenda" "\.org$"))
(setq org-agenda-files (org-find-agenda-files))
(setq org-agenda-start-on-weekday 6)
(setq org-agenda-skip-scheduled-if-done t)
(setq org-agenda-skip-deadline-if-done t)
(setq org-agenda-custom-commands
      '(("S" "Unscheduled actions" tags-todo "TODO=\"ACTION\"+SCHEDULED=\"\"")
        ("D" "Undefined deadlines" tags-todo "TODO=\"WAITING\"+DEADLINE=\"\"")))
(setq org-stuck-projects
        ("ACTION" "WAITING")
Org-Mode agenda view

The agenda serves the same function as the context "next action" lists from GTD; except where contexts are static, the agenda is dynamic, built on-demand and filtered by arbitrary tags (which replace contexts themselves). Further, the "stuck projects," "unscheduled actions," and "undefined deadlines" lists make it easy to find orphaned tasks (now a part of my weekly review).

* ACTION [#A] weekly review                                       :work:home:
  SCHEDULED: <2011-08-20 Sat ++1w>
  - Review stuck projects (C-c a #)
  - Review unscheduled tasks to be done this week. (C-c a S)
  - Review waiting items with no specified deadlines. (C-c a D)
  - Review someday/maybe items. (C-c a t 5 r, C-c a t 6 r)
  - Review the past week's accomplishments. (C-c a a l v w b)
  - Review the upcomming week's actions. (C-c a a v w)

All of the historical logbook data is pulled together in the global logbook view, which I can now inspect separately (again, as part of my weekly review).

Org–Mode logbook view

I use Org–Mode to record virtually everything that I do or need to do, either at work or at home. It really has become my post-GTD, and I have yet to find a requirement that surpasses it. On the contrary, I often find new solutions just as streamlining reveals deeper bottlenecks.

I'll post more of my .emacs and workflow in the future, I'm sure. Until then, feel free to send any questions or comments my way.

leaving Facebook: birthdays

I'm in the process of closing my Facebook account. I never really used it: I'm just not that sold on the idea of a fake social network that rules your life. There are three use cases for me, though, and I need to port the relevant data (or service) elsewhere: the birthday calendar; the instant messaging service, and the photos that are already there.

The birthday calendar

I don't want to lose track of the birthdays that people have published on Facebook. Going forward, I'll have to maintain the calendar myself, and that's fine; but I need to port those birthdays to something more standardized. (That is, likely a regular calendar with iCalendar support.)

Much to my surprise, Facebook makes an iCalendar file available explicitly for birthdays. It's under Events→Birthdays→Export Birthdays. This link provides a webcal: url, which [[!wikipedia webcal desc="wikipedia tells me"]] is an unofficial url for serving iCalendar files. In OS X 1.6, this url was automatically parsed by iCal, which wasn't precisely what I wanted, so I just addressed the same path over http: and got a standard .ics file in my Downloads.

I already have a 'Birthdays' calendar in Google Calendar (which I'll probably be trying to move away from at some point, too) so I just imported this .ics file and merged it into the existing calendar. There's definitely birthdays in there that I don't really care about (sorry, peoples!), but I can filter those down as they come up.

MobileOrg for journaling

I suppose that now is as good a time as any to point out that I'm using mobileorg's capture feature to take these notes. The asyncronous syncing of the system should make it relatively easy to port these notes back into a desktop when I return (albeit via my slice). The plaintext format leaves me feeling in control of the content, too.

There will be a bit of an impedance mismatch between org and markdown, but it shouldn't be too bad. Who knows: I might even be able to automate the process.

MobileOrg push by way of git

Following up from yesterday, I now have a fully automated MobileOrg environment. Simply pushing into my org file git repository provokes a post-receive hook that calls a bit of elisp:

#!/usr/bin/emacs --script

(load "~/.emacs")
(setq org-mobile-directory "~/public_html/org")

Setting org-mobile-directory in the hook allows me to keep it more generalized in .emacs (that is, via /ssh:, so I can run org-mobile-push and, especially, org-mobile-pull from a desktop.

Now, when I do a git push, I also get this (among other, more verbose logging) in my stderr:

remote: Files for mobile viewer staged

MobileOrg push

I just spent the last hour and a half fighting with webdav, emacs, and MobileOrg. I thought that I had all of this settled a while ago, but, as before, org-mode just keeps surprising me with new functionality that I hadn't yet realized that I needed. Now I can capture from my mobile, as well as update todo states.

Next up, I want to do the org-mobile-push from the emacs running on my slice, rather than from Aquamacs running on the desktop; and I want to dispatch it as a post-commit hook in my bare orgfile git repo.

Safari bookmarks, git repositories, and automatic updating

I recently added ~/Library/Safari/Bookmarks.plist to my homedir git repository in the misguided hope that it would be a magically sensible way to keep my bookmarks sync'd between my various systems. This evening was the first real test:

Kay:~ janderson$ pgit pull
remote: Counting objects: 9, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 5 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (5/5), done.
From ssh://
   9d1b3c1..5fdae45  master     -> origin/master
Updating 9d1b3c1..5fdae45
 Library/Safari/Bookmarks.plist |  Bin 1951 -> 2498 bytes
 1 files changed, 0 insertions(+), 0 deletions(-)
Already up-to-date.

Not only did the day's changes propagate to my local system, but Safari implemented the change immediately, in the current running process, in the current window, without intervention. I'm sure this has something to do with fsevents, but it's just one more example of the extent of behavior you can get away with if you implement a system properly in the first place. (After all: it's not as though Apple had this use case in mind.)

Of course, the true test will be how well the file format copes with an n-way merge... but I'll cross that bridge when git blows up in my face.


I use a couple of git repositories in my home directory to track and sync my configuration and org files across multiple platforms. Originally I used a single repository for everything, tracked at ~/.git, but when I split the two concerns I knew that I would want a simple way to manage all of my local git repositories at once. Inspired by my use of existing pssh-style commands, I wrote a quick (not quite so) parallel pgit:


for repo in ~ ~/org
    echo 1>&2 $repo
    cd $repo
    git $@
    cd - >/dev/null

I want to improve this at some point with a configurable repository list (likely a custom section in ~/.gitconfig) and actual parallel execution, but at least for day-to-day, this has already been satisfying to use.