aboutsummaryrefslogtreecommitdiff
path: root/.ai
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-15 23:12:14 -0500
committerCraig Jennings <c@cjennings.net>2026-05-15 23:12:14 -0500
commitcd8b6e9e9c40e2fcd83104457afae1b286924a0e (patch)
treef02f0baabbcbad324315ca1bf8deb3cc2713773a /.ai
parentea5e55da714e13ba64bb34ae7603f2c8ed6fc129 (diff)
downloadrulesets-cd8b6e9e9c40e2fcd83104457afae1b286924a0e.tar.gz
rulesets-cd8b6e9e9c40e2fcd83104457afae1b286924a0e.zip
chore(ai): wrap stale-cleanup + bats harness for audit/install-ai
Two arcs this session: closed two stale todo entries (/lint-org retroactively, pull-ordering doc proactively after writing the missing protocols.org paragraph), then built scripts/tests/audit.bats and scripts/tests/install-ai.bats covering the three deferred destructive edges from yesterday's fold-epic test plan. A dotemacs cross-project handoff for a cj-scan nested-fence bug landed during commit staging and shipped as its own commit, separate from the test-harness work. archive-done moved three DONE level-2 entries to Rulesets Resolved.
Diffstat (limited to '.ai')
-rw-r--r--.ai/sessions/2026-05-15-23-10-stale-cleanup-and-audit-install-ai-bats.org87
1 files changed, 87 insertions, 0 deletions
diff --git a/.ai/sessions/2026-05-15-23-10-stale-cleanup-and-audit-install-ai-bats.org b/.ai/sessions/2026-05-15-23-10-stale-cleanup-and-audit-install-ai-bats.org
new file mode 100644
index 0000000..0e485f9
--- /dev/null
+++ b/.ai/sessions/2026-05-15-23-10-stale-cleanup-and-audit-install-ai-bats.org
@@ -0,0 +1,87 @@
+#+TITLE: Session Context — stale todo cleanup + protocols pull-ordering doc
+#+AUTHOR: Craig Jennings & Claude
+#+DATE: 2026-05-15
+
+* Summary
+
+** Active Goal
+
+Started as stale-entry cleanup (=/lint-org= at =todo.org:1292= was shipped 2026-05-14 but never flipped). Surfaced one partially-stale entry at =todo.org:36= during the audit; chose to actually do the remaining protocols.org pull-ordering documentation work rather than defer it. Then took the =[#C]= sibling at =todo.org:1766= (bats test harness for =make audit= + =make install-ai= edge cases) as the evening task. A cross-project handoff from a parallel dotemacs session landed during commit staging and got absorbed as its own commit.
+
+** Decisions
+
+- =/lint-org= and the pull-ordering doc task were both genuinely stale → flipped to =DONE= with retroactive =CLOSED:= dates.
+- Pull-ordering entry at =todo.org:36= was partially stale (step 1 shipped, step 2 hadn't). Option 1: rewrite the body to reflect post-fold framing (no separate claude-templates pull anymore) and do the protocols.org documentation work in this session.
+- Test harness location =scripts/tests/= (colocate with the scripts being tested), not =.ai/scripts/tests/= as the TODO body said — the TODO body was carried forward from the wrong mental model. Audit and install-ai are rulesets-only utilities, not =.ai/= templates.
+- Test framework: bats 1.13.0 (parallels the elisp ERT pattern for =todo-cleanup= and =lint-org=).
+- Test isolation: redirect =HOME= per test, scaffold synthetic project trees under =HOME/code/=, leave canonical pointing at the real one (resolved relative to each script's =$0=). PATH stubs for =fzf= and =find= cover the interactive and race-condition edges.
+- The =.ai/-missing= FAIL branch in =audit.sh:161= is a defensive race-condition guard that can't be timed by black-box test. Exercised via a PATH-stubbed =find= that injects a fabricated path; the loop hits the FAIL branch on the ghost and continues to the real project.
+- Cross-project handoff disposition (cj-scan nested-fence fix from dotemacs): three-commit split — dotemacs fix first (separate concern), test harness, then todo updates. Handoff file deleted after processing (the work is captured in git + the =DONE [#C]= entry in =Rulesets Resolved=).
+
+** Data Collected / Findings
+
+- bats 1.13.0 is installed at =/usr/bin/bats=.
+- =make test= now totals 352 green: 296 pytest + 1 skipped + 22 lint-org ERT + 23 todo-cleanup ERT + 6 audit bats + 5 install-ai bats. Up from 341.
+- Phase A inbox scan only looks at =./inbox/= at the project root. Post-fold the canonical's inbox lives at =claude-templates/inbox/=, which Phase A doesn't see. The dotemacs handoff dropped there earlier today; my 18:25 startup missed it. Surfaced only when staging commits at 22:50. Filed as a =[#B]= bug.
+- Auto-push observed: =origin/main= advanced from =8577a88= → =7ef200a= at 23:04:39, 26 seconds after committing 7ef200a. No =PostCommit= hook in =~/.claude/= or =.git/hooks/=. No =git push= in this session's command history between the early-session push and the pre-push reconcile. Source unknown — likely a Magit =after-save-hook= or a parallel Claude session.
+- Canonical pytest with the cj-scan fix: 302 passed, 1 skipped (matches the handoff's verification).
+
+** Files Modified
+
+Rulesets (5 commits pushed to =origin/main=):
+- =cdf3909 docs(protocols): add startup pull-ordering rule= — new =** Startup Pull Ordering — Rulesets Before Project= subsection under =IMPORTANT - MUST DO= in both canonical (=claude-templates/.ai/protocols.org=) and project copy (=.ai/protocols.org=).
+- =8577a88 docs(todo): close /lint-org and pull-ordering doc tasks= — todo flips on =/lint-org= (retroactive =CLOSED: [2026-05-14 Thu]=) and the pull-ordering doc task.
+- =dc1661c fix(cj-scan): suppress detection inside nested non-cj begin_* blocks= — dotemacs handoff absorbed. =claude-templates/.ai/scripts/cj-scan.py= gains a =wrapper_type= state machine; =test_cj_scan.py= gains =TestCjScanNestedFencesIgnored= (6 tests); =todo.org= =Rulesets Resolved= gets a new DONE entry.
+- =7ef200a test(scripts): add bats harness for audit + install-ai edge cases= — =scripts/tests/audit.bats= (140 lines, 6 tests), =scripts/tests/install-ai.bats= (103 lines, 5 tests), Makefile =test:= target extended with a bats stanza.
+- =ea5e55d docs(todo): close test harness; file Phase A inbox-scan bug= — test-harness task flipped to DONE; new =[#B]= filed at line ~1792 for the Phase A inbox-scan blind spot.
+
+Working-tree artifacts:
+- =claude-templates/inbox/2026-05-15-handoff-from-dotemacs-cj-scan-nested-fence-fix.org= — deleted (one-time signal absorbed).
+- =claude-templates/inbox/= directory removed (was empty).
+
+** Next Steps
+
+- =[#B]= open at =todo.org:~1792= (post-archive): extend Phase A inbox discovery to also scan =claude-templates/inbox/= when the canonical is in-repo. Also settle whether cross-project handoffs file into =./inbox/= or stay in =claude-templates/inbox/= — the =inbox-send= script's target-project logic is where to decide.
+- Investigate the auto-push source. The pre-push reconcile caught it cleanly tonight, but a non-trivial divergence at the wrong moment could surface as a non-fast-forward push abort. Could be Magit, =git config push.autoSetupRemote=, a parallel Claude session, or something else.
+- Carryover still open: =[#C]= Consolidate =claude-templates/Makefile= after fold; =DOING [#A]= memory-sync (pending VERIFY on stow approach); =[#A]= =/update-skills=, =create-documentation=, 2026-05-04 audit review pass.
+
+* Session Log
+
+** Startup (18:25 CDT)
+
+Clean startup — previous session wrapped cleanly (no =session-context.org=), inbox absent, no cross-agent traffic, no reminders, no pending decisions. Read the 5 most recent session Summaries. Last session (today, 15:13–18:19) closed the /Consolidate .ai/ template infrastructure/ epic. Surfaced one stale entry at =todo.org:1292= (=/lint-org=, shipped 2026-05-14 but never flipped) and offered top open A items.
+
+** Stale entry cleanup
+
+Craig asked to fix the stale entry and then check for others. Flipped =/lint-org= at =todo.org:1292= → =DONE [#A]= with =CLOSED: [2026-05-14 Thu]= per the depth-based completion rule (level-2 → keyword flip + CLOSED line + body retained).
+
+Audit of remaining open level-2 entries against recent commits surfaced one partially-stale entry at =todo.org:36= (=Document rulesets + claude-templates pull-before-project ordering in protocols.org=). Body listed two action items: step 1 (rulesets pull in =startup.org= Phase A.0) had shipped 2026-05-15 as part of the claude-templates fold; step 2 (state the rule in =protocols.org=) had not. Also the framing was outdated — post-fold there's no separate claude-templates pull anymore.
+
+Craig picked option 1 (rewrite the body to reflect step 1 done + drop the claude-templates framing). Rewrote the heading to =Document startup pull-ordering rule in protocols.org= and trimmed the body to isolate the remaining work.
+
+** Did the remaining work — protocols.org paragraph
+
+Edited canonical =claude-templates/.ai/protocols.org= first (per canonical-source rule), then rsynced into =.ai/protocols.org=. Added new =** Startup Pull Ordering — Rulesets Before Project= subsection under =IMPORTANT - MUST DO=, placed between "Always Check the Time" and "Session Context File" (chronologically lining up with Phase A.0 firing first at session start). Three paragraphs: the ordering + what each pull lands, the dirty/merge resolution rule with the no-auto-stash/merge/rebase guardrail, pointer back to =startup.org= Phase A.0 for the mechanics.
+
+Flipped =todo.org:36= → =DONE [#B]= with =CLOSED: [2026-05-15 Fri]= and a one-line resolution note pointing at the new subsection.
+
+** Commit + push
+
+Step 0 reconcile clean (0/0). Voice-mode check showed =.ai/notes.org= tracked → general-voice mode, no approval gate. Two commits:
+
+- =cdf3909 docs(protocols): add startup pull-ordering rule= — both =.ai/protocols.org= copies, +16 lines total. =/voice= fired #3 (-ing analysis) and #27 (passive → active).
+- =8577a88 docs(todo): close /lint-org and pull-ordering doc tasks= — todo flips. =/voice= fired #30 (fragment in prose) and #31 (noun-ified verb).
+
+Pre-push reconcile 0 behind / 2 ahead; pushed cleanly to =origin/main=.
+
+** Test harness for audit + install-ai (option 4)
+
+Craig picked the =[#C]= sibling at =todo.org:1766= for the bats test harness. Flipped to =DOING=. Phase 0 walk: bats 1.13.0 available, no existing harness in tree, scripts under =scripts/= (not =.ai/scripts/=). Proposed Phase 2 design with five points: location =scripts/tests/= (corrects the TODO body which said =.ai/scripts/tests/= — those scripts are rulesets-only, not template content), bats as the tool, HOME-redirect per test for isolation, fzf stub for the interactive case, ~8 tests covering the three deferred edges plus happy-path sanity. Craig: "proceed."
+
+Built two bats files. =scripts/tests/audit.bats= — 6 tests covering clean-sweep, drift detection, =--apply= convergence, dirty-skip, =--apply --force= clobber, and the .ai/-missing loop-continuation edge. The .ai/-missing race-condition guard at line 161 of audit.sh can't be timed by black-box test, so the test stubs =find= via PATH override to inject a fabricated =.ai/= path and confirms the loop hits the FAIL branch and continues to the real project. =scripts/tests/install-ai.bats= — 5 tests covering happy path with explicit PROJECT, =--track= gitkeep stubs, refusal on existing =.ai/=, notes.org placeholder substitution, and the fzf-pick form with a stubbed fzf (=head -n 1=).
+
+Extended =Makefile= =test:= target with a third stanza globbing =scripts/tests/*.bats=. Description updated from "Run the .ai/scripts/ test suites (pytest + ERT)" to "Run all test suites (pytest + ERT + bats)".
+
+Verification: =make test= runs clean — 296 pytest + 1 skipped + 22 lint-org ERT + 23 todo-cleanup ERT + 6 audit bats + 5 install-ai bats = 352 green, no regressions. Each new bats file ran independently first before the full suite run, so failures wouldn't get masked by upstream noise.
+
+Flipped =todo.org:1766= → =DONE [#C]= with =CLOSED: [2026-05-15 Fri]=.