diff options
Diffstat (limited to '.ai/scripts/lint-org.el')
| -rw-r--r-- | .ai/scripts/lint-org.el | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/.ai/scripts/lint-org.el b/.ai/scripts/lint-org.el index 47e8bf1..1bd4582 100644 --- a/.ai/scripts/lint-org.el +++ b/.ai/scripts/lint-org.el @@ -38,6 +38,7 @@ ;; empty-heading bare stars with no title ;; malformed-priority-cookie [#x]-shaped token org rejected ;; level2-done-without-closed completed level-2 task with no CLOSED +;; task-missing-last-reviewed open level-2 task with no :LAST_REVIEWED: ;; subtask-done-not-dated level-3+ done sub-task still a DONE keyword ;; dated-log-heading-active-timestamp dated-log heading with a live SCHEDULED/DEADLINE ;; (anything else) surfaced as judgment with checker name @@ -526,6 +527,42 @@ the live file on the next `task-sorted'." "level-2 DONE/CANCELLED has no CLOSED date — add CLOSED: [YYYY-MM-DD Day]; task-sorted's aging step archives an undated completed task immediately")))))))) ;;; --------------------------------------------------------------------------- +;;; task-missing-last-reviewed check (claude-rules/todo-format.md) +;; +;; A task is stamped `:LAST_REVIEWED:' when it is *created*, not a review cycle +;; later. An agent filing a task has just written its body and graded its +;; priority, which is a review by any honest reading — so a fresh task that +;; carries no stamp reads as "never reviewed" and lands at the top of the next +;; staleness batch, where re-reviewing it is pure ceremony. Every task filed +;; during the 2026-07-23 sweep hit exactly that, which is what prompted the rule. +;; +;; Judgment-only, deliberately. The stamp's whole value is that its date is +;; true, and nothing here can know when an unstamped task was actually last +;; looked at. Auto-stamping today's date would convert a "nobody has reviewed +;; this" signal into a false "reviewed today" one — worse than the gap it +;; closes. Flag it; a human or the filing workflow supplies the honest date. +;; +;; Scope matches `task-review-staleness.sh' exactly (level-2, open keyword, +;; priority cookie), so the checker and the staleness count never disagree +;; about which headings are in the review pool. + +(defun lo--check-task-missing-last-reviewed () + "Flag an open level-2 task with a priority cookie and no `:LAST_REVIEWED:'." + (save-excursion + (goto-char (point-min)) + (let ((case-fold-search nil)) + (while (re-search-forward "^\\*\\* \\(TODO\\|DOING\\|VERIFY\\) \\[#[A-D]\\]" nil t) + (let ((hline (line-number-at-pos)) + (entry-end (save-excursion (outline-next-heading) (point)))) + (save-excursion + (forward-line 1) + (unless (re-search-forward "^[ \t]*:LAST_REVIEWED:[ \t]*[[0-9]" + entry-end t) + (lo--emit-judgment + 'task-missing-last-reviewed hline + "task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed")))))))) + +;;; --------------------------------------------------------------------------- ;;; level-3+ dated-header check (claude-rules/todo-format.md) ;; ;; The inverse of the level-2 check above. A completed sub-task — a heading at @@ -627,6 +664,7 @@ left unmodified and mechanical entries are recorded with :preview t." (lo--check-empty-headings) (lo--check-malformed-priority-cookies) (lo--check-level2-done-without-closed) + (lo--check-task-missing-last-reviewed) (lo--check-subtask-done-not-dated) (lo--check-dated-log-active-timestamp) (when (and (not lo-check-only) (buffer-modified-p)) |
