diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-20 15:06:17 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-20 15:06:17 -0400 |
| commit | e9bd073b8133c50a2df425196e32fdf3f5c4c2bd (patch) | |
| tree | ace469011d84044a78f93a2e6883de673b9a198d /.ai/workflows/task-review.org | |
| parent | 49898a8c364430abf792567d2a51ac09db97a94f (diff) | |
| download | rulesets-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.org | 97 |
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. |
