aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.ai/sessions/2026-05-11-16-18-todo-cleanup-archive-done-and-clean-todo.org75
1 files changed, 75 insertions, 0 deletions
diff --git a/.ai/sessions/2026-05-11-16-18-todo-cleanup-archive-done-and-clean-todo.org b/.ai/sessions/2026-05-11-16-18-todo-cleanup-archive-done-and-clean-todo.org
new file mode 100644
index 0000000..7142029
--- /dev/null
+++ b/.ai/sessions/2026-05-11-16-18-todo-cleanup-archive-done-and-clean-todo.org
@@ -0,0 +1,75 @@
+#+TITLE: Session Context — todo-cleanup --archive-done mode + clean-todo workflow
+#+AUTHOR: Craig Jennings & Claude
+#+DATE: 2026-05-11
+
+* Summary
+
+** Active Goal
+
+Build the =--archive-done= mode for =.ai/scripts/todo-cleanup.el= test-first (ERT — the repo's first elisp tests), then wire it into the session lifecycle: have wrap-up run it automatically, and add a =clean-todo= workflow as the on-demand entry point. =--archive-done= moves every level-2 subtree whose TODO state is DONE or CANCELLED out of a project's "Open Work" section into its "Resolved" section, subtree intact.
+
+** Decisions
+
+- Real project =todo.org= files (work, health, finances, jr-estate, …) are *examples only* — surveyed for structural variety, not copied or committed (privacy: =.ai/= is committed and pushed to cjennings.net). Tests use synthetic fixtures.
+- Canonical-source procedure for any =.ai/scripts/= or =.ai/workflows/= file: edit in =~/projects/claude-templates/= first, rsync into rulesets, commit in both. Craig confirmed this as standard procedure. (Saved as a project memory.)
+- =--archive-done= is its own mode — archive only, doesn't run the hygiene passes; run both for a full cleanup.
+- Section matching: a unique level-1 heading containing "Open Work" (case-insensitive) and one containing "Resolved". Zero or >1 matches → skip with a message, no crash. Only direct level-2 children move; a DONE entry nested under an open parent stays. A level-2 DONE with open level-3 children moves intact.
+- Test seam: the CLI dispatch fires only when the trailing =command-line-args-left= look like a real invocation (recognized flags / readable non-flag paths), so the ERT suite can =require= the file without triggering it. No test-only variable in the source.
+- Reversed the original "opt-in, never run by default" stance on =--archive-done= — Craig wants wrap-up to run it. Wrap-up commits show the diff before push, so it's reviewable.
+- The =clean-todo= workflow leaves the cleaned =todo.org= uncommitted — the summary is the review point; Craig commits the diff if it looks right. Never auto-commit.
+
+** Data Collected / Findings
+
+- =.ai/scripts/= and =.ai/workflows/= are byte-identical mirrors of =~/projects/claude-templates/.ai/=. The startup rsync (=rsync -a --delete=) overwrites this repo's copies — an edit made only here gets clobbered on the next session start of any project. Hence the edit-in-claude-templates-first rule.
+- Real-world section-heading naming varies: =<Project> Open Work= / =<Project> Resolved= (rulesets, work, jr-estate), =Health Open Work= / =Health Resolved Work=, =gloss Open Work= / bare =Resolved=, =Danneel Project Resolved/Event Log=, lowercase =winvm open work= / =winvm resolved=. Some files (whisper-claude) have no such sections — level-1 =* TODO= / =* DONE= directly; =--archive-done= skips those.
+- Done states per the script's =org-todo-keywords=: DONE, CANCELLED.
+- Emacs 30.2 at =/usr/bin/emacs=. =make test= → 240 pytest + 13 ERT, all green; byte-compile clean.
+
+** Files Modified
+
+claude-templates (edited there, rsync'd into rulesets):
+- =.ai/scripts/todo-cleanup.el= — rewritten: added =--archive-done= mode (=tc-archive-done-in-file= + helpers =tc--find-section=, =tc--subtree-end=, =tc--subtree-region=, =tc--done-level-2-children=); extracted the CLI dispatch into =tc-main= behind a =tc--cli-invocation-p= guard; added a =lexical-binding= cookie; reflowed one over-long docstring. Hygiene mode behavior unchanged. Trailing-newline normalization on moved subtrees so they don't drag blank lines into Resolved.
+- =.ai/scripts/tests/test-todo-cleanup.el= — new. 13 ERT tests (one DONE moves; multiple + CANCELLED; structural headings stay; nested-under-open stays; level-2 DONE with open children moves intact; EOF/no-final-newline; missing source/target section; ambiguous "Resolved"; lowercase headings; idempotency; =--check= preview + its idempotency; realistic-sample integration). Synthetic inline-string fixtures + one committed sample file.
+- =.ai/scripts/tests/fixtures/todo-sample.org= — new. Realistic synthetic todo.org exercising the structural variety.
+- =Makefile= — extended =test-scripts= to also run every =tests/test-*.el= ERT suite (=set -e= loop, generic glob).
+- =.ai/workflows/wrap-it-up.org= — Step 3 split into "Hygiene pass" + "Archive completed work" subsections; added the =--archive-done= invocation (real run + a =--check= preview line); step title and wrap-up checklist updated.
+- =.ai/workflows/clean-todo.org= — new. On-demand workflow: hygiene pass → =--archive-done= → summarize, leave the diff uncommitted. Overview / When to Use / 3 steps / Principles / Living Document.
+- =.ai/workflows/INDEX.org= — registered =clean-todo.org= under "Tasks and planning" with trigger phrases.
+
+rulesets only:
+- =Makefile= — added a =test= target (pytest + ERT over =.ai/scripts/tests/=).
+- =todo.org= — marked the =--archive-done= task DONE, moved it to =* Rulesets Resolved=.
+
+** Next Steps
+
+- Everything committed + pushed. claude-templates (origin/main): =516095a feat(todo-cleanup): add --archive-done mode with ERT test suite= → =8627ca2 docs(workflows): run todo-cleanup --archive-done in wrap-up= → =462d932 docs(workflows): add clean-todo workflow=. rulesets (origin/main): =571494b= (feat) → =f7152b4 docs(todo): mark --archive-done task done= → =9dadf33 docs(workflows): run todo-cleanup --archive-done in wrap-up= → =83d48bd docs(workflows): add clean-todo workflow= → wrap-up commit.
+- Three ways to clean todo.org now: automatic at wrap-up; the =clean-todo= workflow on demand ("clean up todo.org" / "clean-todo"); or just ask. =--archive-done --check= for a dry run.
+- Carryover from before this session, still open in =todo.org=: =/update-skills= skill, =create-documentation= skill, the 2026-05-04 audit review pass, plus the dormant =[#B]= "fold claude-templates into rulesets" and "add =make audit=" tasks.
+
+* Session Log
+
+** Startup + task selection (13:21 CDT)
+
+Ran startup — clean tree, no interrupted session, empty inbox, no reminders. Craig picked the "todo.org cleanup script" task: =TODO [#B] Add =--archive-done= mode to =.ai/scripts/todo-cleanup.el== (todo.org:1748). TDD, test-first. Settled: real todo.org files are examples only (not committed — privacy), synthetic fixtures instead; edit lands in claude-templates first, syncs to rulesets, commits in both.
+
+Surveyed ~25 real todo.org files across ~/code and ~/projects for structural variety. Read the existing =todo-cleanup.el= (hygiene passes: bogus state-log deletion + orphan-planning detection; =--check= for report-only). Designed the =--archive-done= implementation (section finding, level-2 done-child collection, subtree extract/delete/reinsert at end of Resolved, idempotency by construction).
+
+** Implementation (TDD)
+
+Wrote =tests/test-todo-cleanup.el= first (13 ERT cases), then implemented. Snag: the original top-level =(when noninteractive ...)= dispatch would fire — and consume =command-line-args-left=, killing the test run — when =require='d from the test file. Fix: extracted it into =tc-main= behind =tc--cli-invocation-p=, which only returns non-nil when the trailing args look like a real invocation, so a test run's trailing =-f ert-run-tests-batch-and-exit= doesn't trigger it. Second snag: =(tc-test--sample-file)= read =load-file-name= at test-run time when it's nil — captured the directory into a =defconst= at load time instead. 13/13 green. Smoke-tested the CLI (=--archive-done --check= preview → real run → re-run = 0 moved → idempotent). Byte-compile clean. Added trailing-newline normalization on moved subtrees.
+
+** Makefile wiring
+
+Craig asked whether the Makefile runs the tests — it didn't (claude-templates' =test-scripts= ran pytest only; rulesets had no test target). Extended =test-scripts= to also run every =tests/test-*.el= ERT suite (=set -e= loop over a generic glob), and added a =test= target to rulesets' Makefile doing the same. Verified: =make test= → 240 pytest + 13 ERT. Folded the Makefile change into the feat commit. Ran =/voice= (general mode — #13 em-dash reduction), got approval, committed + pushed: rulesets =571494b feat= + =f7152b4 docs(todo)=, claude-templates =516095a feat=. Also moved the task to =* Rulesets Resolved= in =todo.org=.
+
+** Wire --archive-done into wrap-up
+
+Craig: "let's have wrap-it-up do the --archive-done." Reversed the original "opt-in only" design (his call). Edited =wrap-it-up.org= Step 3 — split into "Hygiene pass" + "Archive completed work" subsections, added the =--archive-done= invocation (real run + a =--check= preview), updated the step title and the wrap-up checklist. Edited in claude-templates, rsync'd to rulesets. Ran =/voice= (general — nothing fired; fixed a tense slip "already ran" → "already runs" myself), got approval, committed + pushed: =8627ca2= / =9dadf33 docs(workflows): run todo-cleanup --archive-done in wrap-up=.
+
+** clean-todo workflow
+
+Craig asked for a general workflow =clean-todo.org=: hygiene pass → =--archive-done= → summarize, leave the diff uncommitted for review. Wrote =.ai/workflows/clean-todo.org= (Overview / When to Use / 3 steps / Principles / Living Document) in claude-templates, registered it in INDEX.org under "Tasks and planning" with trigger phrases, rsync'd to rulesets, verified the INDEX drift check passes. Ran =/voice= (general — #30 jargon-fragment fix on the trailing "Registered in INDEX.org" line). Craig pre-authorized "commit and push when done" — committed + pushed: =462d932= / =83d48bd docs(workflows): add clean-todo workflow=. Saved a project memory: =.ai/scripts/= and =.ai/workflows/= edits go through claude-templates first, then rsync + commit in both.
+
+** Wrap-up
+
+Ran the wrap-it-up workflow — which now (as of this session) runs both the hygiene pass and =--archive-done= on =todo.org=. (Outcome of those passes recorded in the wrap-up commit's diff.)