aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-22 14:29:29 -0500
committerCraig Jennings <c@cjennings.net>2026-05-22 14:29:29 -0500
commitd93937c87d46f45f7c108712fc1b738eda77ae23 (patch)
tree1a755d478a1ffdac24e823960686a2a948d6204f
parent6cc2a1d08a6a6ee10f9acee9b967f36827c0a27e (diff)
downloadrulesets-d93937c87d46f45f7c108712fc1b738eda77ae23.tar.gz
rulesets-d93937c87d46f45f7c108712fc1b738eda77ae23.zip
chore(todo): close add-tests audit items (1 fixed, 1 moot)
-rw-r--r--.ai/session-context.org69
-rw-r--r--todo.org18
2 files changed, 75 insertions, 12 deletions
diff --git a/.ai/session-context.org b/.ai/session-context.org
new file mode 100644
index 0000000..2cb293b
--- /dev/null
+++ b/.ai/session-context.org
@@ -0,0 +1,69 @@
+#+TITLE: Session — language-bundle startup self-sync
+#+DATE: 2026-05-22
+
+* Summary
+
+** Active Goal
+
+Build =scripts/sync-language-bundle.sh=: a per-project language-bundle freshness check wired into startup Phase A. Detect the installed bundle by fingerprint, auto-fix rulesets-owned files (=.claude/rules/*.md=, =.claude/hooks/*=, =githooks/*=), surface drift in project-customizable files (=settings.json=, =CLAUDE.md=) without writing.
+
+** Decisions
+
+- Per-project self-sync is a *script called from startup with an absolute rulesets path*, not a make target. A make target on the boot path adds a Makefile-parse + target-interface layer for no benefit; calling the script directly is the same accepted dependency the =.ai/= rsync already has.
+- Bundle detection is *fingerprint-based, no marker file*: a project "has" language =<lang>= if any of =languages/<lang>/claude/rules/*.md= (the distinguishing rules, e.g. =elisp.md=, =python-testing.md=) exist in the project's =.claude/rules/=. Naturally scopes to opted-in projects.
+- Auto-fix scope = rulesets-owned files only (=.claude/rules/*.md=, =.claude/hooks/*=, =githooks/*=). Surface-only = =settings.json=, =CLAUDE.md= (project may customize). User chose to fold hooks into auto-fix.
+- Exit codes: 0 = no bundle / clean / auto-fixed; 3 = manual action recommended (settings/CLAUDE drift); 1 = usage error. Quiet when clean (like =task-review-staleness.sh=).
+
+** Data Collected / Findings
+
+- =install-lang.sh= COPIES (cp), does not symlink — so there are no per-project language symlinks, only content drift. The only real symlinks are machine-global =~/.claude/= (handled by =make doctor=/=install=).
+- =diff-lang.sh= already walks the installer's file set (generic rules, language =.claude/= tree, githooks); reused its comparison shape.
+- bats tests live in =scripts/tests/*.bats=; =make test= runs them. Style mirrored from =audit.bats= (temp HOME/project, real script, real =languages/= source).
+
+** Files Modified
+
+- =scripts/sync-language-bundle.sh= (new) — the self-sync script.
+- =scripts/tests/sync-language-bundle.bats= (new) — 11 tests, all green.
+- =claude-templates/.ai/workflows/startup.org= + =.ai/workflows/startup.org= mirror — Phase A step 12 + Phase C surfacing bullet.
+
+Shipped: =1ceed70 feat(startup): sync language bundles per project on session launch=, pushed to =origin/main=.
+
+Two ripe-fruit follow-ups (committed locally, not yet pushed):
+- =a785f54 docs(workflows): document GitHub-family assumption in wrap-it-up Step 3.5= (item #1, =:quick:= [#A]).
+- =a4389e8 docs(skills): keep review-code praise honest and unforced= (item #2 + Craig's adjacent "don't explain praise" edit, bundled per Craig's choice).
+- =1477642 chore(todo): close GH-assumption and review-code strengths tasks=.
+
+Mid-session rule change: Craig edited =claude-rules/commits.md= (still uncommitted) to *decouple voice patterns from the approval gate* — publish artifacts always run =/voice personal= (39 patterns) regardless of =.ai/= tracking; the =.ai/=-tracking check now decides only whether the gate fires. Applied to item #2 onward. The feature commit + item #1 predate it (used =/voice= general); item #1 is effectively compliant anyway (already first-person + contractions, no semicolons).
+
+All pushed to origin/main (=1ceed70..6c91a4e=), tree clean except the live session-context. =6c91a4e docs(commits): decouple voice patterns from the approval gate= committed Craig's rule edit; it's symlinked into =~/.claude/rules/= so it's already live.
+
+** Audit-pass cluster (2026-05-04) — in progress, area-by-area
+
+Approach: area-by-area, my choice of order, check-in between batches, freshness-check each item against current reality (humanizer→voice, skills→commands all happened since the audit). Inventory confirmed nearly every referenced artifact still exists (as skill, command, or rule file); only =humanizer= refs are genuinely stale.
+
+Done (all pushed through =1825226=):
+- *Code review* (3) — three-strengths, CI-trust scoping, CLAUDE.md citation modes.
+- *PR responses* (4) — respond-to-review commit-language + thread-resolution; two respond-to-cj-comments items moot (path already gone, humanizer/emacsclient superseded by /voice + VERIFY).
+- *Browser testing* (1 of 3) — headed/headless decision tables in both playwright skills (2e9d5b0). DEFERRED: #1 networkidle/locator refactor (touches helper code, no tests) and #3 emoji sweep (~30 occurrences, 7 files) — both spread-heavy, held for focused passes given the concurrent-edit warning.
+- *Debugging/RCA* (3) — debug env/recent-change capture, root-cause-trace boundary-only defense, five-whys evidence+counterfactual per link (3916dc4).
+
+** Next Steps
+
+- Continue the cluster, next area my choice (~29 items left across ~12 areas; Browser testing, Security, Global rules, Hooks, Languages, Architecture, C4, etc.).
+- The 3 real bundle-bearing projects (chime, gloss = elisp; work = python) self-heal language-bundle drift at their own next startup via step 12 — Craig opted to let them.
+
+* Session Log
+
+** Setup + investigation
+
+Session opened in rulesets. Startup ran clean (40 ok doctor, 0 .ai/ drift after a fleet =make audit APPLY=1= synced 27 projects). Earlier this session: reconciled all 26 AI projects (pushed emacs-wttrin's pending commit, committed google-contacts.el's .gitignore).
+
+Design discussion converged on a per-project language-bundle self-sync for startup. Confirmed via reading =install-lang.sh= / =diff-lang.sh= that bundles are copied (not symlinked) and detectable by fingerprint rule files. User approved option-2 behavior with hooks folded into auto-fix.
+
+Now implementing TDD: bats test first, then the script, then wire into startup Phase A (canonical =claude-templates/.ai/workflows/startup.org= + rsync mirror).
+
+** Implementation + smoke test
+
+Wrote the bats test (10 cases) red, then the script green. One scaffold bug: the test helper didn't seed CLAUDE.md, so the elisp bundle (which ships one) tripped the surface check. Fixed the helper — all green.
+
+Smoke-tested against a *copy* of chime's real =.claude/= (no writes to the real project): it correctly auto-fixed 6 stale generic rules + a drifted =validate-el.sh=, but flagged =CLAUDE.md (missing)= → exit 3 on every run. That's wrong: CLAUDE.md is seed-only in install-lang (never overwritten without FORCE), so a missing/differing one isn't actionable via =make install-<lang>=, and =diff-lang.sh= already skips it. Dropped CLAUDE.md from the surface set entirely (settings.json only), added a regression test asserting an absent CLAUDE.md is not drift. Re-smoke: chime copy converges silently on re-run, exit 0. 11 tests green, shellcheck clean, =make lint= clean, full =make test= green (302 pytest + ERT + all bats).
diff --git a/todo.org b/todo.org
index 528019c..010fc20 100644
--- a/todo.org
+++ b/todo.org
@@ -787,8 +787,8 @@ Each item below is a one-line summary of a sub-TODO further down. Tick the box w
- [ ] [#B] =start-work=: claim-before-justify rollback risk
**** Tests / TDD
-- [ ] [#B] =add-tests=: fix missing =typescript-testing.md= reference or add ruleset
-- [ ] [#B] =add-tests=: explicit exceptions to "all three categories per function"
+- [X] [#B] =add-tests=: fix missing =typescript-testing.md= reference or add ruleset (moot — ruleset now exists)
+- [X] [#B] =add-tests=: explicit exceptions to "all three categories per function"
**** Debugging / RCA
- [X] [#B] =debug=: capture environment + recent-change context before hypotheses
@@ -1000,19 +1000,13 @@ then says rolling back is required if justification fails. Consider moving
claiming after Gate 1 for personal todo tasks, or make the rollback steps
explicit per tracker with stored prior state.
-*** TODO [#A] =add-tests=: fix missing =typescript-testing.md= reference or add the ruleset
+*** 2026-05-22 Fri @ 14:28:41 -0500 Verified add-tests typescript-testing.md reference resolves (moot)
-Phase 3 references =typescript-testing.md=, but this repo currently has Python
-and Elisp testing rules only. Either add the TypeScript ruleset or change the
-skill to discover project-local JS/TS testing conventions instead of pointing
-to a missing file.
+Resolved since the audit: =languages/typescript/claude/rules/typescript-testing.md= now exists, and =add-tests/SKILL.md:68= references it by bare filename, the same way it references =python-testing.md= (both get copied into a project's =.claude/rules/=). The "missing file" premise no longer holds. No edit needed.
-*** TODO [#A] =add-tests=: add explicit exceptions to "all three categories per function"
+*** 2026-05-22 Fri @ 14:28:41 -0500 Added a category-exception protocol to add-tests
-The Normal/Boundary/Error rule is useful, but some functions are pure adapters,
-generated code, tiny wrappers, or framework glue. Add an exception protocol:
-state why a category does not apply, and cover the behavior at the integration
-or E2E level when unit categories would test framework behavior.
+Added an exception note to step 7 (proposal) in =add-tests/SKILL.md=: pure adapters, generated code, tiny pass-through wrappers, and framework glue may skip a category that would only re-test the framework, but the skip must be stated and justified in the plan and the behavior covered at integration/E2E level — never a silent omission. Step 12 (write) now points back to "honor documented category exceptions."
*** 2026-05-22 Fri @ 14:25:37 -0500 Added environment + recent-change capture to debug Phase 1