   (string= (org-entry-get nil "STYLE") "habit"))
 
 (defun pjs-org-task-p ()
+  "A task is an entry with a TODO cookie."
   (member (nth 2 (org-heading-components)) org-todo-keywords-1))
 
 (defun pjs-org-project-p ()
+  "A project is a task with at least one sub-task."
   ;; it has a DEADLINE?
   (save-restriction
     (widen)

        project-p))))

(defun pjs-org-stuck-project-p ()
  (save-restriction
    (widen)
    (when (pjs-org-project-p)
      (let ((subtree-end (save-excursion (org-end-of-subtree t)))
            (stuck-p t))
        (save-excursion
          (while (and stuck-p
                      (< (point) subtree-end))
            (when (and (pjs-org-task-p)
                       (or (org-entry-get nil "SCHEDULED")
                           (org-entry-get nil "DEADLINE")
                           (let ((closed-dt (org-entry-get nil "CLOSED")))
                             (and closed-dt
                                  (time-less-p (org-read-date t t "-7d")
                                               (org-read-date t t closed-dt))))))
              (setq stuck-p nil))
            (outline-next-heading))
          stuck-p)))))


(defun pjs-org-agenda-sort-created (a b)
  (let* ((a-marker (get-text-property 0 'org-marker a))
         (b-marker (get-text-property 0 'org-marker b))
         (created-a (let ((created-a (org-entry-get a-marker "CREATED")))
                      (when created-a
                        (org-read-date t t created-a))))
         (created-b (let ((created-b (org-entry-get b-marker "CREATED")))
                      (when created-b
                        (org-read-date t t created-b)))))
    (cond
     ((and created-a created-b)
      (if (time-less-p created-a created-b)
