aboutsummaryrefslogtreecommitdiff
path: root/.ai/workflows/task-review.org
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-20 15:06:17 -0400
committerCraig Jennings <c@cjennings.net>2026-05-20 15:06:17 -0400
commite9bd073b8133c50a2df425196e32fdf3f5c4c2bd (patch)
treeace469011d84044a78f93a2e6883de673b9a198d /.ai/workflows/task-review.org
parent49898a8c364430abf792567d2a51ac09db97a94f (diff)
downloadrulesets-e9bd073b8133c50a2df425196e32fdf3f5c4c2bd.tar.gz
rulesets-e9bd073b8133c50a2df425196e32fdf3f5c4c2bd.zip
feat(workflows): add task-review list-hygiene habit
The new task-review.org workflow is the daily habit that retires the old date-coverage scan. It surfaces the oldest-unreviewed top-level tasks, walks them one at a time, and records each outcome — keep, re-grade, kill, mark DOING, or edit — stamping :LAST_REVIEWED: as it goes. It's a pure Claude workflow, no elisp. open-tasks.org displays the list; this one changes it. task-review-staleness.sh gains a --list mode that emits the N oldest-unreviewed tasks (line, review date, heading), oldest first, so the workflow walks a deterministic batch instead of eyeballing todo.org. Never-reviewed and unparseable-date tasks sort oldest. Seven new bats cases cover ordering, the count limit, exclusions, and output format; count mode is unchanged. startup.org gains the matching nudge. Phase A counts tasks unreviewed for >7 days and Phase C surfaces one line when that count is non-zero, pointing at the workflow. It lives in the template startup.org rather than the project-only startup-extras layer, so every project picks it up the same way it picks up the wrap-up health check. The INDEX entry is added with the "task review" triggers the rename freed up.
Diffstat (limited to '.ai/workflows/task-review.org')
-rw-r--r--.ai/workflows/task-review.org97
1 files changed, 97 insertions, 0 deletions
diff --git a/.ai/workflows/task-review.org b/.ai/workflows/task-review.org
new file mode 100644
index 0000000..febb986
--- /dev/null
+++ b/.ai/workflows/task-review.org
@@ -0,0 +1,97 @@
+#+TITLE: Task Review Workflow
+#+AUTHOR: Craig Jennings & Claude
+#+DATE: 2026-05-20
+
+* Overview
+
+A short, daily list-hygiene habit. Each run surfaces the handful of top-level tasks that have gone longest without a review, walks them with Craig one at a time, and records the outcome — re-grade, kill, mark in-progress, or just confirm it's still right — stamping =:LAST_REVIEWED:= as it goes.
+
+The point is /trust/: when Craig opens =todo.org=, the priorities and wording should feel accurate. Tasks drift — an =[#A]= from six months ago may not be urgent now, a commitment keeps getting deferred without ever being killed, a body loses the context that made it actionable. Walking a small rotating batch every day keeps the list honest without a big periodic purge.
+
+This is *not* =open-tasks.org=, which just displays the list or picks the next task. This workflow *changes* tasks. Full design and rationale: [[file:../../docs/design/task-review.org][docs/design/task-review.org]].
+
+* When to Use This Workflow
+
+User says one of: "task review", "review tasks", "let's do a task review", "groom my tasks", "task-review".
+
+Cadence is daily and rotational — the batch is the oldest-unreviewed tasks, so consecutive days cover different tasks. At the default batch size of 7 over ~80 open tasks, the full list rotates about every 12 days.
+
+* Phase A: Precondition
+
+Confirm =todo.org= exists at the project root. If it doesn't, say "this project has no =todo.org= to review" and stop — there's nothing to do.
+
+* Phase B: Select the batch
+
+Run the staleness script in list mode to get the oldest-unreviewed top-level tasks. Default batch size is 7; let Craig override if he asks for more or fewer.
+
+#+begin_src bash
+.ai/scripts/task-review-staleness.sh --list todo.org 7
+#+end_src
+
+Each output line is tab-separated: =<line> <LAST_REVIEWED-or-NONE> <heading>=. The list is already ordered oldest-first (never-reviewed tasks sort before dated ones), so walk it top to bottom. Selection only includes depth-2 =**= headings that are =TODO=/=DOING=/=VERIFY= with an =[#A]=/=[#B]=/=[#C]= cookie — DONE/CANCELLED and deeper headings are out by construction.
+
+If the list is empty, report "nothing to review — every task has been looked at recently" and stop.
+
+Read =todo.org= once now so the body of each selected task is in context for the walk. Don't re-read per task.
+
+* Phase C: Walk the batch
+
+Get today's date once for the stamp:
+
+#+begin_src bash
+date "+%Y-%m-%d"
+#+end_src
+
+Then take the tasks one at a time, in list order. For each, show Craig the heading, its priority, when it was last reviewed (or "never"), and a one-line reminder of the body. Then ask what to do. The actions:
+
+| Action | What it does | Stamp =:LAST_REVIEWED:=? |
+|--------+--------------+--------------------------|
+| *Keep* | Still correct as-is — no change beyond recording the review | Yes |
+| *Re-grade A/B/C* | Change the priority cookie to =[#A]= / =[#B]= / =[#C]= | Yes |
+| *Kill* | Abandon it: =TODO=/=DOING= → =CANCELLED= plus a =CLOSED: [YYYY-MM-DD Day]= line | No (it leaves the pool as CANCELLED) |
+| *Doing* | =TODO= → =DOING= (no-op if already DOING/VERIFY) | Yes |
+| *Edit* | Reword the heading or body — do it with Craig, then record the review | Yes |
+| *Skip* | Not now — leave it untouched so it resurfaces next run | No |
+
+Keep is the common case — most tasks are still right and just need re-stamping. Be decisive and quick; this is a 5-minute habit, not a planning session.
+
+*** Stamping =:LAST_REVIEWED:=
+
+Set =:LAST_REVIEWED:= to today's date (from above) in the task's =:PROPERTIES:= drawer:
+
+- If the task already has a =:PROPERTIES:= drawer, update or add the =:LAST_REVIEWED:= line inside it.
+- If it has no drawer, insert one immediately after the heading — or, when the heading carries a =DEADLINE:=/=SCHEDULED:=/=CLOSED:= planning line, immediately after that line (org requires the planning line to sit directly under the heading, with the drawer below it):
+
+#+begin_example
+** TODO [#A] Some topic :tag:
+:PROPERTIES:
+:LAST_REVIEWED: 2026-05-20
+:END:
+Body...
+#+end_example
+
+The exact date string matters: =task-review-staleness.sh= and the wrap-up health check both parse =:LAST_REVIEWED: YYYY-MM-DD=.
+
+*** Killing a task
+
+Follow the completion rules in [[file:../../claude-rules/todo-format.md][todo-format.md]]. A killed top-level =**= task stays task-shaped: change the keyword to =CANCELLED=, add a =CLOSED: [YYYY-MM-DD Day]= line under the heading (generate with =date "+%Y-%m-%d %a"=), and leave the priority and tags intact. It's then a candidate for =--archive-done= at the next cleanup. Don't stamp =:LAST_REVIEWED:= on a kill — it's leaving the review pool anyway.
+
+* Phase D: Close out
+
+When the batch is done (or Craig calls it early):
+
+1. Summarize what changed — re-grades, kills, anything marked DOING — in a couple of lines. Don't list the keeps individually; "the rest were confirmed as-is" is enough.
+2. The edits are already written to =todo.org=. If Craig keeps =todo.org= open in Emacs, remind him to revert the buffer so his editor picks up the changes (and flag that any unsaved edits he had open could collide — re-running picks up whatever's on disk).
+
+* Common Mistakes
+
+1. *Re-reading =todo.org= per task* — read it once in Phase B; the in-memory view is canonical for the walk.
+2. *Stamping a killed task* — a kill leaves the pool; no =:LAST_REVIEWED:= needed.
+3. *Walking more than the batch* — staleness ordering means the batch is the right set; don't expand it into a full-list review.
+4. *Turning it into planning* — this is hygiene (is each task still right?), not "what should I do today". For that, use =open-tasks.org=.
+5. *Drifting the date format* — =:LAST_REVIEWED:= must be =YYYY-MM-DD=, or the staleness script won't read it.
+6. *Marking a kill DONE instead of CANCELLED* — DONE means finished, CANCELLED means abandoned. A task review kills tasks that shouldn't be done at all.
+
+* Living Document
+
+Adjust the batch size if 7/day feels wrong — smaller for a tighter daily touch, larger to rotate faster. If the action set grows (e.g. a "defer with a date" action), add it to the Phase C table and note the stamping behavior.