diff options
Diffstat (limited to '.ai/scripts/task-review-staleness.sh')
| -rwxr-xr-x | .ai/scripts/task-review-staleness.sh | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/.ai/scripts/task-review-staleness.sh b/.ai/scripts/task-review-staleness.sh index ed43712..50e0257 100755 --- a/.ai/scripts/task-review-staleness.sh +++ b/.ai/scripts/task-review-staleness.sh @@ -19,9 +19,14 @@ # deeper headings, and cookie-less headings are not review units. # # A task is stale (count mode), and sorts oldest (list mode), when its -# :LAST_REVIEWED: property is missing or unparseable (NIL sorts first), or -# when its age strictly exceeds the threshold (age > N days; age == N is -# still fresh). +# :LAST_REVIEWED: property is missing (NIL sorts first) or when its age +# strictly exceeds the threshold (age > N days; age == N is still fresh). +# +# :LAST_REVIEWED: accepts a bare date (2026-07-09) or an org-native +# timestamp ([2026-07-09 Thu] or <2026-07-09 Thu ...>); both normalize to +# the ISO date. A value that is present but parses to neither is a data +# error: the script warns loudly to stderr (file:line:value) and leaves it +# out of the stale count rather than silently treating it as never-reviewed. set -euo pipefail @@ -46,7 +51,7 @@ num="$2" # only the property drawer between a qualifying heading and the next heading # is scanned. extract_tasks() { - awk ' + awk -v fname="$todo_file" ' function flush() { if (in_task) printf "%s\t%s\t%s\n", hline, (have_lr ? lr : "NONE"), heading } @@ -65,7 +70,21 @@ extract_tasks() { v = $0 sub(/^[ \t]*:LAST_REVIEWED:[ \t]*/, "", v) sub(/[ \t]*$/, "", v) - lr = v; have_lr = 1 + raw = v + # Accept org-native stamps: strip a leading [ or < (inactive/active + # timestamp bracket) and take the leading ISO date, so [2026-07-09 Thu] + # and 2026-07-09 both normalize to 2026-07-09. + sub(/^[[<]/, "", v) + if (match(v, /^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/)) { + lr = substr(v, RSTART, RLENGTH); have_lr = 1 + } else { + # Present but unparseable — a data error, not "never reviewed". Warn + # loudly (file:line:value) instead of silently folding it into the + # stale count, where a re-review in the same bad format would never + # drop the number and nothing would explain why. + printf "task-review-staleness: %s:%d: unparseable :LAST_REVIEWED: %s (expected YYYY-MM-DD or [YYYY-MM-DD Day])\n", fname, NR, raw > "/dev/stderr" + lr = "INVALID"; have_lr = 1 + } next } END { flush() } @@ -98,9 +117,16 @@ while IFS=$'\t' read -r hline value heading; do continue fi - # Unparseable date → treat as NIL (stale). + # Malformed stamp: extract_tasks already warned. A data error is not + # "never reviewed", so it stays out of the stale count. + if [ "$value" = "INVALID" ]; then + continue + fi + + # A shape-valid but impossible date (e.g. 2026-13-45) slips past the awk + # regex; warn and skip rather than silently counting it. if ! rev_epoch=$(date -d "$value" +%s 2>/dev/null); then - count=$((count + 1)) + echo "task-review-staleness: $todo_file: unparseable :LAST_REVIEWED: $value" >&2 continue fi |
