Tracking actions through a series of meetings

Table of Contents

Introduction

Org-mode can be used very well for taking notes and for capturing action items during the meeting. This keeps the tasks inside the notes and works really well for planning out projects.

When documenting a series of meetings with Org-mode, a different work flow is required. Such a meeting series usually has a set of tasks which are continuously being defined during the meetings, and which need to be tracked from meeting to meeting until completion. So usually the meeting notes contains the current list of tasks. Done tasks disappear from the meeting notes, but still need to be available to the person who is running the series of meeting.

Requirements

To use the work flow described here, you will need the bleeding edge git version of 2011-03-30 or any release that was created after this date. Basic task tracking has been possible with Org, of course, since day one, but exporting without DONE tasks is a only recent addition.

Also, this tutorial assumes that you are using the helper functions shown in section Custom code. This is not strictly necessary - you could do the corresponding steps by hand - but if you are using this work flow more often, you may appreciate these tools.

Setup

Use a special Org file to document the meetings and to track the actions. In the file, I have the following setup.

#+TODO: TODO(t) | CANCELED(c) DONE(d)
#+OPTIONS: tasks:todo

Of course you can define the TODO keywords any way you like. The #+OPTIONS line arranges for DONE tasks to be excluded from export, so that when you send around the list of actions to the participants, these completed tasks will not clutter the list. If you want to keep DONE tasks in the list, either always or occasionally, modify this line to say #+OPTIONS: tasks:t.

How to identify tasks

It is useful to identify a task in a unique way, so that you can get back to it easily in the next meeting. The method I am choosing here is to simply number the tasks sequentially, in the sequence they come up. The custom code below defines a command to create tasks in this way, to ensure that the sequential number is indeed not already taken. To bind this command to a key, use (for example)

(define-key org-mode-map "\C-cn" 'org-mactions-new-numbered-action)

The command org-mactions-new-numbered-action uses the specification in org-mactions-numbered-action-format to insert a task like this:

** TODO Action #2:                                 :#2:

You can also call the command with a prefix argument in order to insert an inline-task.

With the default setup, the action starts with "Action #2", and it is tagged by "#2" to that I can tag other stuff relating to this action and search for it.

The work flow

Before a meeting

For each meeting I start a new top-level section in the document for the notes. In the notes I create new actions and leave them there for the time being.

I also have a top-level section "ACTIONS" in the file. This section contains all the actions from previous meetings, each action identified by its unique number. I have this section right after the meeting notes sections, so that I can easily export the latest meeting notes together with the action list, simply by narrowing the buffer to the two sequential trees. Here is an example what this might look like

* Notes from <2011-03-16 Wed>                                       :ARCHIVE:
* Notes from <2011-03-23 Wed>                                       :ARCHIVE:
* Notes from <2011-03-30 Wed>
** Present at meeting
,   - [X] Peter
,   - [X] Sarah
,   - [X] Sam
** Agenda
,   - Comments and corrections to last meting notes
,   - Reports from the sub teams
,   - Discussion
,   - Final round
** Notes
,   ...
, 
* ACTIONS
,  This is the general list of Actions
** DONE Action #1 Inventory of equipment                           :#1:Sarah:
** DONE Action #2 Definition of main goals                         :#2:Peter:
** TODO Action #4 Talk to companies                                  :#4:Sam:

During the meeting

During the meeting, take notes and create new actions. You could add these new actions immediately to the global list, or you could define the actions inside the notes for now. Below I will show how to copy or move the actions to the general list.

When I create actions, I also tag them with the names of people who are responsible, so that it later becomes easy to track progress and to send reminders.

After the meeting

After the meeting, I organize the notes of the current meeting until they are ready to be sent out. I like to keep the newly defined actions inside the meeting notes, to highlight them as new. Once satisfied with the notes, the new actions need to be integrated with the general list of actions.

Copying the actions from the meeting notes to the action list

I then copy the new actions from the last meeting to the ACTIONS section. For this task I use the command M-x org-mactions-collect-todos-in-subtree. It will copy all the actions in a subtree and put them into the kill ring, so that I can simply paste them with C-c C-x C-y into the ACTIONS list. There I organize the actions, change the sequence, create subsections with related actions together etc. Some groups have trivial task lists, then the list just stays simple and flat. For complex consortia I do a lot of analysis, structuring, and ordering.

Sending out the notes

To send the meeting notes and the current list of actions, I narrow the buffer to the node with the meeting notes and the node with the action list, export to the desired format, and mail it out.

Deactivate tasks in the meeting notes

I then deactivate any actions in the meeting notes I just sent around by marking the entire new notes tree with an ARCHIVE tag. Then, TODO lists and other Agenda views will get entries only from the ACTIONS tree, not from the meeting notes. Instead of copying, you could also move (refile) the actions to the ACTIONS tree, but I like to keep them deactivated in the notes, so that I have a copy of the notes exactly as sent around, in the file. The idea is that the meeting notes are fixed, and all procedural stuff with the actions will be added and tracked in the ACTIONS tree.

Between meetings

Between meetings, I use the ACTIONS tree to generate reminders for people in the list, check DONE tasks off etc. Before the next meeting, I create an agenda view to show me which actions have been closed during the last period. I create this view in the following way: With the cursor in the actions tree I do

C-c a < < a         ;; Agenda view restricted on subtree
v L                 ;; turn on logging

I extract what needs to be reported to the group and add that to the invitation mailing for the next meeting. I also attach an export of the current ACTIONS tree to the agenda, for reference during the following meeting. The DONE items will not be on that tree anymore. The nice thing is that the members of the meeting always have an uncluttered list of actions, while I as the responsible person still have all the old tasks and the history of the entire project at my finger tips.

Conclusion

This setup has worked really well for me, both for meetings that happen locally, and for meetings with international groups who meet via telephone/video conferencing.

In the section below, I welcome contributions by anyone, describing additional ideas and modification to the workflow.

Custom code

Here is some custom code to help entering numbered actions, and to collect TODO items in a subtree into a flat list.

(defcustom org-mactions-numbered-action-format "TODO Action #%d "
  "Default structure of the headling of a new action.
    %d will become the number of the action."
  :group 'org-edit-structure
  :type 'string)

(defcustom org-mactions-change-id-on-copy t
  "Non-nil means make new IDs in copied actions.
If an action copied with the command `org-mactions-collect-todos-in-subtree'
contains an ID, that ID will be replaced with a new one."
  :group 'org-edit-structure
  :type 'string)

(defun org-mactions-new-numbered-action (&optional inline)
  "Insert a new numbered action, using `org-mactions-numbered-action-format'.
    With prefix argument, insert an inline task."
  (interactive "P")
  (let* ((num (let ((re "\\`#\\([0-9]+\\)\\'"))
                (1+ (apply 'max 0
                           (mapcar
                            (lambda (e)
                              (if (string-match re (car e))
                                  (string-to-number (match-string 1 (car e)))
                                0))
                            (org-get-buffer-tags))))))
         (tag (concat "#" (number-to-string num))))
    (if inline
        (org-inlinetask-insert-task)
      (org-insert-heading 'force))
    (unless (eql (char-before) ?\ ) (insert " "))
    (insert (format org-mactions-numbered-action-format num))
    (org-toggle-tag tag 'on)
    (if (= (point-max) (point-at-bol))
        (save-excursion (goto-char (point-at-eol)) (insert "\n")))
    (unless (eql (char-before) ?\ ) (insert " "))))

(defun org-mactions-collect-todos-in-subtree ()
  "Collect all TODO items in the current subtree into a flat list."
  (interactive)
  (let ((buf (get-buffer-create "Org TODO Collect"))
        (cnt 0) beg end string s)
    (with-current-buffer buf (erase-buffer) (org-mode))
    (org-map-entries
     (lambda ()
       (setq beg (point) end (org-end-of-subtree t t) cnt (1+ cnt)
             string (buffer-substring beg end)
             s 0)
       (when org-mactions-change-id-on-copy
         (while (string-match "^\\([ \t]*:ID:\\)[ \t\n]+\\([^ \t\n]+\\)[ \t]*$"
                              string s)
           (setq s (match-end 1)
                 string (replace-match (concat "\\1 "
                                               (save-match-data (org-id-new)))
                                       t nil string))))
       (with-current-buffer buf (org-paste-subtree 1 string)
                            (goto-char (point-max))))
     (format "TODO={%s}" (regexp-opt org-not-done-keywords))
     'tree)
    (if (= cnt 0)
        (message "No TODO items in subtree")
      (message "%d TODO entries copied to kill ring" cnt)
      (prog1 (with-current-buffer buf
               (kill-new (buffer-string)))
        (kill-buffer buf)))))

Other ideas and remarks about this workflow

Exporting to LaTeX (by Eric S Fraga)

I use LaTeX to create the minutes I circulate to the people that attended a meeting. I have adopted Carsten's workflow but have customised some of the behaviour to better suit the LaTeX export. The customisations address primarily the formatting of the actions and identifying the person responsible for each action.

  1. I customise the export options to not include TODO keywords or tags and to not number the sections, using:
    #+OPTIONS: tags:nil todo:nil num:nil toc:nil
    

    The toc option is not strictly necessary but minutes of meetings are typically only a few pages so a table of contents is seldom required. However, it can be useful for generating a list of actions.

  2. The numbering of actions is done by explicitly putting the number into the headline. I do this by customising the org-numbered-action-format variable to the string
    "TODO %d. \\action{?}"
    
  3. To support this type of headline, I have defined the \action LaTeX macro:
    #+latex_header: \newcommand{\action}[1]{\marginpar{\fbox{#1}}}
    

    I will typically put the name or initials of the person responsible for taking the action in lieu of the ? as the argument to the action macro in the headline, such as:

    , ** TODO 3. \action{ESF} Prepare plan.         :#3:
    

    The macro, on export, will place the person's name or initials in the right margin of the page with a box around it, making it very easy to identify who has actions and who does not.

    I do customise the LaTeX export further but those customisations are not specific to minute taking.

Documentation from the http://orgmode.org/worg/ website (either in its HTML format or in its Org format) is licensed under the GNU Free Documentation License version 1.3 or later. The code examples and css stylesheets are licensed under the GNU General Public License v3 or later.