diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-18 21:03:50 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-18 21:03:50 -0500 |
| commit | ddbd47fbbea06e71456b7bc4228626d3a126bf28 (patch) | |
| tree | 06211963ee5fbb85b8c9eb0d4f2b860e5c74dfa1 /.ai/scripts/tests/test-lint-org.el | |
| parent | d2b1bef686fd6c22a6303c13829f88bdd110fa7b (diff) | |
| download | rulesets-ddbd47fbbea06e71456b7bc4228626d3a126bf28.tar.gz rulesets-ddbd47fbbea06e71456b7bc4228626d3a126bf28.zip | |
feat(todo-cleanup): dated-seal archiving and planning-line strip on convert
Two batched changes to the todo hygiene tooling.
Dated-seal archiving: --archive-done aging now keeps one month in-file (retain default 7 → 31, named as tc-archive-retain-days-default) and a new --seal renames the working task-archive.org to resolved-YYYY-MM-DD.org beside it, letting the next aging start a fresh working file. Dating the sealed file by the seal run rather than the calendar quarter is what avoids mislabeling a task closed late in a quarter and archived after the boundary. The unparseable-CLOSED case is now explicit in the contract: a keyword-complete task with no readable close date ages out too. The sealed file inherits the todo file's gitignore status.
Planning-line strip: --convert-subtasks now drops the whole planning line when it rewrites a done sub-task to a dated event-log entry, not just the CLOSED cookie. A dated-log heading carries its date in the heading, so an active SCHEDULED/DEADLINE left on it pins the finished entry to the agenda as weeks-overdue forever (org renders any active planning timestamp, keyword or not). New lint-org checker dated-log-heading-active-timestamp backstops any that predate this. todo-format.md's sub-task and VERIFY completion rules gain the strip step.
Diffstat (limited to '.ai/scripts/tests/test-lint-org.el')
| -rw-r--r-- | .ai/scripts/tests/test-lint-org.el | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/.ai/scripts/tests/test-lint-org.el b/.ai/scripts/tests/test-lint-org.el index 8e3e190..30a79bd 100644 --- a/.ai/scripts/tests/test-lint-org.el +++ b/.ai/scripts/tests/test-lint-org.el @@ -739,6 +739,48 @@ missing-rules violation." (judgments (lo-test--judgments (plist-get out :issues)))) (should-not (member 'subtask-done-not-dated (lo-test--checkers judgments))))) +;;; dated-log-heading-active-timestamp check (stale SCHEDULED/DEADLINE on a +;;; completed dated-log entry — the home 2026-07-17 agenda-pollution bug) + +(ert-deftest lo-dated-log-active-scheduled-is-flagged () + "A dated-log entry still carrying an active SCHEDULED is flagged: org renders +it on the agenda forever despite the missing keyword." + (let* ((out (lo-test--run + "* Open Work\n\n** TODO [#B] Parent\n*** 2026-06-20 Sat @ 10:00:00 -0500 trip booked\nSCHEDULED: <2026-06-18 Thu>\nBody.\n")) + (judgments (lo-test--judgments (plist-get out :issues)))) + (should (= 0 (plist-get out :fixes))) ; judgment-only, never auto-fixed + (should (member 'dated-log-heading-active-timestamp (lo-test--checkers judgments))))) + +(ert-deftest lo-dated-log-active-deadline-is-flagged () + "An active DEADLINE on a dated-log entry is flagged too." + (let* ((out (lo-test--run + "* Open Work\n\n** TODO [#B] Parent\n*** 2026-06-20 Sat @ 10:00:00 -0500 shipped\nDEADLINE: <2026-06-25 Thu>\n")) + (judgments (lo-test--judgments (plist-get out :issues)))) + (should (member 'dated-log-heading-active-timestamp (lo-test--checkers judgments))))) + +(ert-deftest lo-dated-log-clean-entry-not-flagged () + "A dated-log entry with no active planning timestamp is correct — not flagged." + (let* ((out (lo-test--run + "* Open Work\n\n** TODO [#B] Parent\n*** 2026-06-20 Sat @ 10:00:00 -0500 done cleanly\nBody only.\n")) + (judgments (lo-test--judgments (plist-get out :issues)))) + (should-not (member 'dated-log-heading-active-timestamp (lo-test--checkers judgments))))) + +(ert-deftest lo-dated-log-inactive-timestamp-not-flagged () + "An inactive [..] timestamp doesn't render on the agenda, so it isn't flagged — +only active <..> planning timestamps are the defect." + (let* ((out (lo-test--run + "* Open Work\n\n** TODO [#B] Parent\n*** 2026-06-20 Sat @ 10:00:00 -0500 recorded\nSCHEDULED: [2026-06-18 Thu]\n")) + (judgments (lo-test--judgments (plist-get out :issues)))) + (should-not (member 'dated-log-heading-active-timestamp (lo-test--checkers judgments))))) + +(ert-deftest lo-dated-log-active-scheduled-on-live-todo-not-flagged () + "A live TODO (keyword present) that legitimately carries an active SCHEDULED is +not a dated-log heading, so this checker leaves it alone." + (let* ((out (lo-test--run + "* Open Work\n\n** TODO [#B] Parent\n*** TODO [#C] real upcoming task\nSCHEDULED: <2026-06-18 Thu>\n")) + (judgments (lo-test--judgments (plist-get out :issues)))) + (should-not (member 'dated-log-heading-active-timestamp (lo-test--checkers judgments))))) + ;;; --------------------------------------------------------------------------- ;;; structural heading checks (org-lint gaps) |
